查詢數(shù)據(jù)庫(kù)表某字段含“亂碼”的數(shù)據(jù)的一個(gè)方法
超過(guò)十多年行業(yè)經(jīng)驗(yàn),技術(shù)領(lǐng)先,服務(wù)至上的經(jīng)營(yíng)模式,全靠網(wǎng)絡(luò)和口碑獲得客戶,為自己降低成本,也就是為客戶降低成本。到目前業(yè)務(wù)范圍包括了:網(wǎng)站建設(shè)、成都做網(wǎng)站,成都網(wǎng)站推廣,成都網(wǎng)站優(yōu)化,整體網(wǎng)絡(luò)托管,微信平臺(tái)小程序開發(fā),微信開發(fā),手機(jī)APP定制開發(fā),同時(shí)也可以讓客戶的網(wǎng)站和網(wǎng)絡(luò)營(yíng)銷和我們一樣獲得訂單和生意!
說(shuō)明:
在某些情況下,由于字符集不兼容等問(wèn)題,數(shù)據(jù)庫(kù)中的記錄可能存在“亂碼”,本文就是介紹一個(gè)SQL語(yǔ)句把亂碼的記錄找到。
什么是“亂碼”
這是首先需要明確的,其實(shí)如果數(shù)據(jù)庫(kù)記錄了“半個(gè)漢字”實(shí)際他只會(huì)記錄一個(gè)“?”(Oracle),如果記錄的亂碼恰好變成另外一個(gè)“漢字”和殘余字符,那這個(gè)新的“漢字”是不能用下面的方法找出來(lái)的。
適用范圍
查找記錄中是否含有ascii碼(特別是“?”)的方式找到“亂碼”的記錄。
SQL模板
Select
*
from
Table_A
t
Where
instr(Name,chr(1))0
or
instr(Name,chr(2))0
or
instr(Name,chr(3))0
or
instr(Name,chr(4))0
or
instr(Name,chr(5))0
or
instr(Name,chr(6))0
or
instr(Name,chr(7))0
or
instr(Name,chr(8))0
or
instr(Name,chr(9))0
or
instr(Name,chr(10))0
or
instr(Name,chr(11))0
or
instr(Name,chr(12))0
or
instr(Name,chr(13))0
or
instr(Name,chr(14))0
or
instr(Name,chr(15))0
or
instr(Name,chr(16))0
or
instr(Name,chr(17))0
or
instr(Name,chr(18))0
or
instr(Name,chr(19))0
or
instr(Name,chr(20))0
or
instr(Name,chr(21))0
or
instr(Name,chr(22))0
or
instr(Name,chr(23))0
or
instr(Name,chr(24))0
or
instr(Name,chr(25))0
or
instr(Name,chr(26))0
or
instr(Name,chr(27))0
or
instr(Name,chr(28))0
or
instr(Name,chr(29))0
or
instr(Name,chr(30))0
or
instr(Name,chr(31))0
or
instr(Name,chr(32))0
or
instr(Name,chr(33))0
or
instr(Name,chr(34))0
or
instr(Name,chr(35))0
or
instr(Name,chr(36))0
or
instr(Name,chr(37))0
or
instr(Name,chr(38))0
or
instr(Name,chr(39))0
or
instr(Name,chr(40))0
or
instr(Name,chr(41))0
or
instr(Name,chr(42))0
or
instr(Name,chr(43))0
or
instr(Name,chr(44))0
or
instr(Name,chr(45))0
or
instr(Name,chr(46))0
or
instr(Name,chr(47))0
or
instr(Name,chr(48))0
or
instr(Name,chr(49))0
or
instr(Name,chr(50))0
or
instr(Name,chr(51))0
or
instr(Name,chr(52))0
or
instr(Name,chr(53))0
or
instr(Name,chr(54))0
or
instr(Name,chr(55))0
or
instr(Name,chr(56))0
or
instr(Name,chr(57))0
or
instr(Name,chr(58))0
or
instr(Name,chr(59))0
or
instr(Name,chr(60))0
or
instr(Name,chr(61))0
or
instr(Name,chr(62))0
or
instr(Name,chr(63))0
or
instr(Name,chr(64))0
or
instr(Name,chr(65))0
or
instr(Name,chr(66))0
or
instr(Name,chr(67))0
or
instr(Name,chr(68))0
or
instr(Name,chr(69))0
or
instr(Name,chr(70))0
or
instr(Name,chr(71))0
or
instr(Name,chr(72))0
or
instr(Name,chr(73))0
or
instr(Name,chr(74))0
or
instr(Name,chr(75))0
or
instr(Name,chr(76))0
or
instr(Name,chr(77))0
or
instr(Name,chr(78))0
or
instr(Name,chr(79))0
or
instr(Name,chr(80))0
or
instr(Name,chr(81))0
or
instr(Name,chr(82))0
or
instr(Name,chr(83))0
or
instr(Name,chr(84))0
or
instr(Name,chr(85))0
or
instr(Name,chr(86))0
or
instr(Name,chr(87))0
or
instr(Name,chr(88))0
or
instr(Name,chr(89))0
or
instr(Name,chr(90))0
or
instr(Name,chr(91))0
or
instr(Name,chr(92))0
or
instr(Name,chr(93))0
or
instr(Name,chr(94))0
or
instr(Name,chr(95))0
or
instr(Name,chr(96))0
or
instr(Name,chr(97))0
or
instr(Name,chr(98))0
or
instr(Name,chr(99))0
or
instr(Name,chr(100))0
or
instr(Name,chr(101))0
or
instr(Name,chr(102))0
or
instr(Name,chr(103))0
or
instr(Name,chr(104))0
or
instr(Name,chr(105))0
or
instr(Name,chr(106))0
or
instr(Name,chr(107))0
or
instr(Name,chr(108))0
or
instr(Name,chr(109))0
or
instr(Name,chr(110))0
or
instr(Name,chr(111))0
or
instr(Name,chr(112))0
or
instr(Name,chr(113))0
or
instr(Name,chr(114))0
or
instr(Name,chr(115))0
or
instr(Name,chr(116))0
or
instr(Name,chr(117))0
or
instr(Name,chr(118))0
or
instr(Name,chr(119))0
or
instr(Name,chr(120))0
or
instr(Name,chr(121))0
or
instr(Name,chr(122))0
or
instr(Name,chr(123))0
or
instr(Name,chr(124))0
or
instr(Name,chr(125))0
or
instr(Name,chr(126))0
or
instr(Name,chr(127))0
1. 服務(wù)器指定字符集與客戶字符集不同,而與加載數(shù)據(jù)字符集一致。
解決方法:對(duì)于這種情況,只需要設(shè)置客戶端字符集與服務(wù)器端字符集一致就可以了,具體操作如下:
* 查看當(dāng)前字符集:
SQL select * from sys.props$
2 WHERE NAME=‘NLS_CHARACTERSET’;
NAME value$
NLS_CHARACTERSET ZHS16GBK
可以看出,現(xiàn)在服務(wù)器端Oracle數(shù)據(jù)庫(kù)的字符集為‘ZHS16GBK’
* 根據(jù)服務(wù)器的字符集在客戶端作相應(yīng)的配置或者安裝Oracle的客戶端軟件時(shí)指定:
如果還沒(méi)安裝客戶端,那么在安裝客戶端時(shí),指定與服務(wù)器相吻合的字符集即可;如果已經(jīng)安裝好了客戶端,并且客戶端為 sql*net 2.0 以下版本,進(jìn)入Windows的系統(tǒng)目錄,編輯oracle.ini文件,用US7ASCII替換原字符集,重新啟動(dòng)計(jì)算機(jī),設(shè)置生效;否則,如果,客戶端為 sql*net 2.0 以上版本,在Win98 下 運(yùn) 行REGEDIT,第一步選HKEY_LOCAL_MACHINE,第二步選擇SOFTWARE, 第三步選擇 Oracle, 第四步選擇 NLS_LANG, 鍵 入 與服 務(wù) 器 端 相 同 的 字 符 集
(本例為:HKEY_LOCAL_MACHINE/
SOFTWARE/ORACLE/NLS_LANG :AMERICAN _ AMERICA. ZHS16GBK)。
如果是UNIX客戶端,則:
SQL conn / as sysdba
Connected.
SQL SQL UPDATE sys.PROPS$ SET value$=‘SIMPLIFIED CHINESE’
2 WHERE NAME=‘NLS_LANGUAGE’;
2. 服務(wù)器指定字符集與客戶字符集相同,與加載數(shù)據(jù)字符集不一致。
解決方法:強(qiáng)制加載數(shù)據(jù)字符集與服務(wù)器端字符集一致。要做到這一點(diǎn),可以通過(guò)重新創(chuàng)建數(shù)據(jù)庫(kù),并選擇與原卸出數(shù)據(jù)一致的字符集,然后IMP數(shù)據(jù),這種情況僅僅適用于空庫(kù)和具有同一種字符集的數(shù)據(jù)。
解決這類問(wèn)題,也可以先將數(shù)據(jù)加載到具有相同字符集的服務(wù)器上,然后用轉(zhuǎn)換工具卸出為foxbase 格式或access格式數(shù)據(jù)庫(kù),再用轉(zhuǎn)換工具轉(zhuǎn)入到不同字符集的Oracle數(shù)據(jù)庫(kù)中,這樣就避免了Oracle字符集的困擾。目前數(shù)據(jù)庫(kù)格式轉(zhuǎn)換的工具很多,像power builder5.0以上版本提供的pipeline及Microsoft Access數(shù)據(jù)庫(kù)提供的數(shù)據(jù)導(dǎo)入/導(dǎo)出功能等。
3. 服務(wù)器指定字符集與客戶字符集不同,與輸入數(shù)據(jù)字符集不一致。
對(duì)于這種情況,目前為止都還沒(méi)有太好的解決方法。
通過(guò)上面的了解,我們知道,導(dǎo)致在后期使用數(shù)據(jù)庫(kù)時(shí)出現(xiàn)種種關(guān)于字符集的問(wèn)題,多半是由于在數(shù)據(jù)庫(kù)設(shè)計(jì)、安裝之初沒(méi)有很好地考慮到以后的需要,所以,我們完全可以通過(guò)在服務(wù)器上和客戶端使用相同的字符集來(lái)避免由此類問(wèn)題引出的麻煩
怎樣修改查看Oracle字符集
a.數(shù)據(jù)庫(kù)服務(wù)器字符集select * from nls_database_parameters,其來(lái)源于props$,是表示數(shù)據(jù)庫(kù)的字符集。
b.客戶端字符集環(huán)境select * from nls_instance_parameters,其來(lái)源于v$parameter,
表示客戶端的字符集的設(shè)置,可能是參數(shù)文件,環(huán)境變量或者是注冊(cè)表
c.會(huì)話字符集環(huán)境 select * from nls_session_parameters,其來(lái)源于v$nls_parameters,表示會(huì)話自己的設(shè)置,可能是會(huì)話的環(huán)境變量或者是alter session完成,如果會(huì)話沒(méi)有特殊的設(shè)置,將與nls_instance_parameters一致。
客戶端的字符集要求與服務(wù)器一致,才能正確顯示數(shù)據(jù)庫(kù)的非Ascii字符。如果多個(gè)設(shè)置存在的時(shí)候,alter session環(huán)境變量注冊(cè)表參數(shù)文件
實(shí)際情況
我用select * from nls_database_parameters
PARAMETER VALUE
------------------------------ ------------------------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CHARACTERSET ZHS16GBK
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
PARAMETER VALUE
------------------------------ ------------------------------
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_RDBMS_VERSION 10.2.0.1.0
說(shuō)明我在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)指定的字符集是ZHS16GBK,我用
update sys.props$ set value$='AL32UTF8' where name='NLS_CHARACTERSET';
修改了字符集,但插入中文時(shí)仍然有問(wèn)題,這或許就如上面資料所說(shuō)的通過(guò)修改SYS.PROPS$來(lái)修改主要是對(duì)應(yīng)客戶端的顯示,與存儲(chǔ)無(wú)關(guān),
所以仍舊是亂碼。
然后我重新創(chuàng)建了個(gè)數(shù)據(jù)庫(kù),指定字符集為AL32UTF8,插入中文就沒(méi)問(wèn)題了。
可見(jiàn)我們?nèi)绻跀?shù)據(jù)庫(kù)中顯示中文,在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)一定喲指定好所用的字符集。
1、首先,Oracle查詢編碼:select * from v$nls_parameters;//看看是否GBK
2、如果是用Servlet或者別的,插入數(shù)據(jù)之前輸出一下,看看是否亂碼。
比如:
doPost()
//設(shè)置接受編碼,但你的頁(yè)面也必須是UTF-8
response.setContentType("text/html;charset=UTF-8");
doGet()
//下面方式轉(zhuǎn)一下碼
String username = new String(request.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");