|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
对于insert和delete,event中包含了插入/删除的记录的所有字段的值(太爽了。。)成绩
link:
http://www.eygle.com/special/NLS_CHARACTER_SET_03.htm
2.字符集的变动
数据库创立今后,假如必要修正字符集,一般必要重修数据库,经由过程导进导出的体例来转换。
我们也能够经由过程以下体例变动
ALTERDATABASECHARACTERSET
注重:修正数据库字符集时必需审慎,修正之前必定要为数据库备份。因为不克不及回退这项操纵,因而大概会形成数据丧失大概破坏。
这是最复杂的转换字符集的体例,但其实不老是无效。
这个命令在Oracle8时被引进Oracle,这个操纵在实质上其实不转换任何数据库字符,只是复杂的更新数据库中一切跟字符集相干的信息。
这意味着,你只能在新字符集是旧字符集严厉超集的情形下利用这类体例转换。
所谓超集是指:
以后字符会合的每个字符在新字符会合都能够暗示,并利用一样的代码点
好比良多字符集都是US7ASCII的严厉超集。
假如不是超集,将取得以下毛病:
SQL>ALTERDATABASECHARACTERSETZHS16CGB231280;
ALTERDATABASECHARACTERSETZHS16CGB231280
*
ERRORatline1:
ORA-12712:newcharactersetmustbeasupersetofoldcharacterset
上面我们来看一个测试(以下测试在Oracle9.2.0下举行,Oracle9i较Oracle8i在编码方面有较年夜改动,在Oracle8i中,测试了局大概略有分歧):
SQL>selectname,value$fromprops$wherenamelike%NLS%;NAMEVALUE$------------------------------------------------------------NLS_LANGUAGEAMERICANNLS_TERRITORYAMERICANLS_CURRENCY$NLS_ISO_CURRENCYAMERICANLS_NUMERIC_CHARACTERS.,NLS_CHARACTERSETUS7ASCIINLS_CALENDARGREGORIANNLS_DATE_FORMATDD-MON-RRNLS_DATE_LANGUAGEAMERICAN……………….NLS_NCHAR_CHARACTERSETAL16UTF16NLS_RDBMS_VERSION9.2.0.4.020rowsselected.SQL>selectname,dump(name)fromeygle.test;NAMEDUMP(NAME)------------------------------------------------------测试Typ=1Len=4:178,226,202,212TestTyp=1Len=4:116,101,115,1162rowsselected.
转换字符集,数据库应当在RESTRICTED形式下举行.
c:>sqlplus"/assysdba"SQL*Plus:Release9.2.0.4.0-ProductiononSatNov110:52:302003Copyright(c)1982,2002,OracleCorporation.Allrightsreserved.Connectedto:Oracle9iEnterpriseEditionRelease9.2.0.4.0-ProductionWiththePartitioning,OracleLabelSecurity,OLAPandOracleDataMiningoptionsJServerRelease9.2.0.4.0-ProductionSQL>shutdownimmediateDatabaseclosed.Databasedismounted.ORACLEinstanceshutdown.SQL>STARTUPMOUNT;ORACLEinstancestarted.TotalSystemGlobalArea76619308bytesFixedSize454188bytesVariableSize58720256bytesDatabaseBuffers16777216bytesRedoBuffers667648bytesDatabasemounted.SQL>ALTERSESSIONSETSQL_TRACE=TRUE;Sessionaltered.SQL>ALTERSYSTEMENABLERESTRICTEDSESSION;Systemaltered.SQL>ALTERSYSTEMSETJOB_QUEUE_PROCESSES=0;Systemaltered.SQL>ALTERSYSTEMSETAQ_TM_PROCESSES=0;Systemaltered.SQL>ALTERDATABASEOPEN;Databasealtered.SQL>setlinesize120SQL>ALTERDATABASECHARACTERSETZHS16GBK;ALTERDATABASECHARACTERSETZHS16GBK*ERRORatline1:ORA-12721:operationcannotexecutewhenothersessionsareactiveSQL>ALTERDATABASECHARACTERSETZHS16GBK;ALTERDATABASECHARACTERSETZHS16GBK*ERRORatline1:ORA-12716:CannotALTERDATABASECHARACTERSETwhenCLOBdataexists在Oracle9i中,假如数据库存在CLOB范例字段,那末就不同意对字符集举行转换SQL>
这时候候,我们能够往检察alert<sid>.log日记文件,看CLOB字段存在于哪些表上:
ALTERDATABASECHARACTERSETZHS16GBK
SYS.METASTYLESHEET(STYLESHEET)-CLOBpopulated
ORA-12716signalledduring:ALTERDATABASECHARACTERSETZHS16GBK...
关于分歧情形,Oracle供应分歧的办理计划,假如是用户数据表,一样平常我们能够把包括CLOB字段的表导出,然后drop失落相干工具,
转换后再导进数据库;关于体系表,能够依照以下体例处置:
SQL>truncatetableMetastylesheet;
Tabletruncated.
然后能够持续举行转换!
SQL>ALTERSESSIONSETSQL_TRACE=TRUE;Sessionaltered.SQL>ALTERDATABASECHARACTERSETZHS16GBK;Databasealtered.SQL>ALTERSESSIONSETSQL_TRACE=FALSE;Sessionaltered.
在9.2.0中,转换完成今后,能够经由过程运转catmet.sql剧本来重修Metastylesheet表:
SQL>@?/rdbms/admin/catmet.sql
转换后的数据:
SQL>selectname,value$fromprops$wherenamelike%NLS%;NAMEVALUE$------------------------------------------------------------NLS_LANGUAGEAMERICANNLS_TERRITORYAMERICANLS_CURRENCY$NLS_ISO_CURRENCYAMERICANLS_NUMERIC_CHARACTERS.,NLS_CHARACTERSETZHS16GBK…..NLS_NCHAR_CHARACTERSETAL16UTF16NLS_RDBMS_VERSION9.2.0.4.020rowsselected.SQL>select*fromeygle.test;NAME------------------------------测试test2rowsselected.
提醒:
经由过程设置sql_trace,我们能够跟踪良多数据库的背景操纵,这个工具是DBA经常使用的“利器”之一。
我们复杂看一下数据库变动字符集时的背景处置,我提取了次要的更新部分。
经由过程以下跟踪历程,我们看到数据库在变动字符集的时分,次要更新了12张数据字典表,修正了数据库的原数据,这也证明了我们之前的说法:
这个变动字符集的操纵在实质上其实不转换任何数据库字符,只是复杂的更新数据库中一切跟字符集相干的信息。
updatecol$setcharsetid=:1wherecharsetform=:2updateargument$setcharsetid=:1wherecharsetform=:2updatecollection$setcharsetid=:1wherecharsetform=:2updateattribute$setcharsetid=:1wherecharsetform=:2updateparameter$setcharsetid=:1wherecharsetform=:2updateresult$setcharsetid=:1wherecharsetform=:2updatepartcol$setspare1=:1wherecharsetform=:2updatesubpartcol$setspare1=:1wherecharsetform=:2updateprops$setvalue$=:1wherename=:2update"SYS"."KOTAD$"setSYS_NC_ROWINFO$=:1whereSYS_NC_OID$=:2updateseq$setincrement$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,cache=:7,highwater=:8,audit$=:9,flags=:10whereobj#=:1updatekopm$setmetadata=:1,length=:2wherename=DB_FDO
在这里我们特地改正一个由来和的毛病办法.
常常能够在网上看到如许的变动字符集的办法:
1)用SYS用户名上岸ORACLE。
2)检察字符集内容
SQL>SELECT*FROMPROPS$;
3)修正字符集
SQL>updateprops$setvalue$=新字符集wherename=NLS_CHARACTERSET
4)COMMIT;
我们看到良多人在这个成绩上碰到了凄惨的教导,利用这类体例变动字符集,假如你的value$值输出了不准确的字符集,在8i中那末你
的数据库大概会没法启动,这类情形长短常严峻的,偶然候你必需从备份中举行恢复;假如是在9i中,能够从头启动数据库后再修正回正
确的字符集。可是我们仍旧不倡议利用这类体例举行任何数据库修正,这是一种极为伤害的操纵。
实践受骗我们更新了字符集,数据库启动时会依据数据库的字符集主动的来修正把持文件的字符集,假如字符集能够辨认,更新把持文
件字符集即是数据库字符集;假如字符集不成辨认,那末把持文件字符集更新为US7ASCII.
经由过程更新props$表的体例修正字符集,在Oracle7以后就不该该被利用.
以下是我的测试了局,可是严禁统统不备份的修正研讨,即便是对测试库的。
SQL>updateprops$setvalue$=EYGLEwherename=NLS_CHARACTERSET;1rowupdated.SQL>commit;Commitcomplete.SQL>selectname,value$fromprops$wherenamelike%NLS%;NAMEVALUE$-----------------------------------------------------------------NLS_LANGUAGEAMERICANNLS_TERRITORYAMERICANLS_CURRENCY$NLS_ISO_CURRENCYAMERICANLS_NUMERIC_CHARACTERS.,NLS_CHARACTERSETEYGLENLS_CALENDARGREGORIANNLS_DATE_FORMATDD-MON-RRNLS_DATE_LANGUAGEAMERICAN….NLS_NCHAR_CHARACTERSETZHS16GBKNLS_RDBMS_VERSION8.1.7.1.118rowsselected.从头启动数据库,发明alert.log文件中纪录以下操纵:MonNov0316:11:352003UpdatingcharactersetincontrolfiletoUS7ASCIICompleted:ALTERDATABASEOPEN启动数据库后恢复字符集设置:SQL>updateprops$setvalue$=ZHS16GBKwherename=NLS_CHARACTERSET;1rowupdated.SQL>commit;Commitcomplete.SQL>selectname,value$fromprops$wherenamelike%NLS%;NAMEVALUE$-----------------------------------------------------------------NLS_LANGUAGEAMERICANNLS_TERRITORYAMERICANLS_CURRENCY$NLS_ISO_CURRENCYAMERICANLS_NUMERIC_CHARACTERS.,NLS_CHARACTERSETZHS16GBKNLS_CALENDARGREGORIANNLS_DATE_FORMATDD-MON-RRNLS_DATE_LANGUAGEAMERICAN………NLS_COMPBINARYNLS_NCHAR_CHARACTERSETZHS16GBKNLS_RDBMS_VERSION8.1.7.1.118rowsselected.从头启动数据库后,发明把持文件的字符集被更新:MonNov0316:21:412003UpdatingcharactersetincontrolfiletoZHS16GBKCompleted:ALTERDATABASEOPEN
了解了字符集调剂的外部操纵今后,我们能够容易的指出,以上的办法是不准确的,经由过程后面”ALTERDATABASECHARACTERSET”体例变动字
符集时,Oracle最少必要变动12张数据字典表,而这类间接更新props$表的体例只完成了个中十二分之一的事情,潜伏的完全性隐患是不可思议的。
以是,变动字符集只管要利用一般的路子。
mysql的prepare其实是本地PHP客户端模拟的,并没有根据你mysql的设置做字符集的调整。应该交与mysqlserver端做prepare,同时得调用mysql_set_character_set去操作,server才会按照字符集去做转义。 |
|