明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線(xiàn)學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

檢查有日文片假名的新聞

[摘要]==26個(gè)日文片假名導(dǎo)致Access搜索(80040e14/內(nèi)存溢出)的解決辦法==ゴ ガ ギ グ ゲ ザ ジ ズ ヅ デ ド ポ ベ プ ビ パ ヴ ボ ペ ブ ピ バ ヂ ダ ゾ ゼ 當(dāng)字段內(nèi)包含了這26個(gè)日文字符任意一個(gè)多個(gè)時(shí),就會(huì)導(dǎo)致在執(zhí)行SQL語(yǔ)句中包含了[字段] like '%...
==26個(gè)日文片假名導(dǎo)致Access搜索(80040e14/內(nèi)存溢出)的解決辦法==

ゴ ガ ギ グ ゲ ザ ジ ズ ヅ デ ド ポ ベ プ ビ パ ヴ ボ ペ ブ ピ バ ヂ ダ ゾ ゼ
當(dāng)字段內(nèi)包含了這26個(gè)日文字符任意一個(gè)多個(gè)時(shí),就會(huì)導(dǎo)致在執(zhí)行SQL語(yǔ)句中包含了
[字段] like '%aaaaa%' 或 inStr(1,[字段],'aaaaa',1)>0
這樣的查詢(xún)時(shí),毫無(wú)道理的出現(xiàn)了
"Microsoft JET Database Engine 錯(cuò)誤 '80040e14' 內(nèi)存溢出"的錯(cuò)誤
其他Jet SQL函數(shù)命令未作測(cè)試,大概與字符搜索定位匹配相關(guān)的都可能出錯(cuò)

搜索相關(guān)資料得知被微軟工程師證實(shí)是Access的bug,可能是語(yǔ)法關(guān)系都是微軟的東東
在vbs中 執(zhí)行inStr(1,日文平假名變量,"aaaaa",1)依然要出現(xiàn)錯(cuò)誤
Microsoft VBScript 運(yùn)行時(shí)錯(cuò)誤 錯(cuò)誤 '800a0005' 無(wú)效的過(guò)程調(diào)用或參數(shù): 'instr'


沒(méi)有搜索,因這幾個(gè)字符出現(xiàn)Access的論壇網(wǎng)站搜索無(wú)法進(jìn)行,何等痛苦
昨天一朋友大叫怪事,他的音樂(lè)數(shù)據(jù)庫(kù)無(wú)法搜索了,只有30000條記錄時(shí)是好的
毫無(wú)疑問(wèn),日文片假名是禍根,花幾分鐘把有包含上面的日文替換成"?"搜索順利恢復(fù)
找來(lái)論壇程序用戶(hù)群最大的動(dòng)網(wǎng)dvBBS AC版本 7.0SP2 版測(cè)試,同樣有這個(gè)日文發(fā)帖后 導(dǎo)致無(wú)法搜索并且運(yùn)行時(shí)出錯(cuò)的問(wèn)題
線(xiàn)上去搜索 '80040e14' 內(nèi)存溢出" 的錯(cuò)誤 多的是!

一簡(jiǎn)單有效的解決辦法:
對(duì)這26個(gè)字符進(jìn)行編碼和解碼,可能效率感覺(jué)不理想,測(cè)試下來(lái)問(wèn)題不大,速度影響不是太大

編碼:

Function Jencode(byVal iStr)
if isnull(iStr) or isEmpty(iStr) then
Jencode=""
Exit function
end if
dim F,i,E
' F=array("ゴ","ガ","ギ","グ","ゲ","ザ","ジ","ズ","ヅ","デ",_
' "ド","ポ","ベ","プ","ビ","パ","ヴ","ボ","ペ","ブ","ピ","バ",_
' "ヂ","ダ","ゾ","ゼ")
E=array("Jn0;","Jn1;","Jn2;","Jn3;","Jn4;","Jn5;","Jn6;","Jn7;","Jn8;","Jn9;","Jn10;","Jn11;","Jn12;","Jn13;","Jn14;","Jn15;","Jn16;","Jn17;","Jn18;","Jn19;","Jn20;","Jn21;","Jn22;","Jn23;","Jn24;","Jn25;")
F=array(chr(-23116),chr(-23124),chr(-23122),chr(-23120),_
chr(-23118),chr(-23114),chr(-23112),chr(-23110),_
chr(-23099),chr(-23097),chr(-23095),chr(-23075),_
chr(-23079),chr(-23081),chr(-23085),chr(-23087),_
chr(-23052),chr(-23076),chr(-23078),chr(-23082),_
chr(-23084),chr(-23088),chr(-23102),chr(-23104),_
chr(-23106),chr(-23108))
Jencode=iStr
for i=0 to 25
Jencode=replace(Jencode,F(i),E(i))
next
End Function

解碼:

Function Juncode(byVal iStr)
if isnull(iStr) or isEmpty(iStr) then
Juncode=""
Exit function
end if
dim F,i,E
' F=array("ゴ","ガ","ギ","グ","ゲ","ザ","ジ","ズ","ヅ","デ",_
' "ド","ポ","ベ","プ","ビ","パ","ヴ","ボ","ペ","ブ","ピ","バ",_
' "ヂ","ダ","ゾ","ゼ")
E=array("Jn0;","Jn1;","Jn2;","Jn3;","Jn4;","Jn5;","Jn6;","Jn7;","Jn8;","Jn9;","Jn10;","Jn11;","Jn12;","Jn13;","Jn14;","Jn15;","Jn16;","Jn17;","Jn18;","Jn19;","Jn20;","Jn21;","Jn22;","Jn23;","Jn24;","Jn25;")
F=array(chr(-23116),chr(-23124),chr(-23122),chr(-23120),_
chr(-23118),chr(-23114),chr(-23112),chr(-23110),_
chr(-23099),chr(-23097),chr(-23095),chr(-23075),_
chr(-23079),chr(-23081),chr(-23085),chr(-23087),_
chr(-23052),chr(-23076),chr(-23078),chr(-23082),_
chr(-23084),chr(-23088),chr(-23102),chr(-23104),_
chr(-23106),chr(-23108))
Juncode=iStr
for i=0 to 25
Juncode=replace(Juncode,E(i),F(i))'□
next
End Function

注意,如果直接使用字符不方便(windows還沒(méi)裝日文支持),注釋掉的部分提供有 chr(-23804) ..這樣的定義


[page_break]

這樣
1.
表單輸入保存時(shí),使用Jencode()將這26個(gè)字符先編碼再保存(為什么是這26個(gè)字符,經(jīng)過(guò)全部測(cè)試87個(gè)平假名89個(gè)片假名最終認(rèn)定的)

ゴ 即 chr(-23116) 編碼為 Jn1;
2.
顯示時(shí),則使用 Juncode() 函數(shù)進(jìn)行解碼,還原日文片假名顯示
3.
搜索關(guān)鍵字,也要使用 Jencode() 進(jìn)行編碼后再放入 like里
where [Topic] like '%Jencode(kewwords)%' 使用
才能保證搜索的值和編碼過(guò)的數(shù)據(jù)庫(kù)字段內(nèi)容匹配

==================================

PS:
也可以使用正則表達(dá)式來(lái)改寫(xiě)上面的兩個(gè)函數(shù),或許效率還要更高些
再就是如果 壓根不使用日文,也不需要搜索日文,則解碼部分可以不用,保存數(shù)據(jù)實(shí)直接把這26個(gè)片假名字符替換為空字符或任一字符,比如"□"
拋磚引玉,如果有更本質(zhì)的真正的好方法,謝分享

附:
----------------------------
平假名87個(gè) asc值
-23391 --> -23316
unicode 3040-309F

ぁあぃいぅうぇえぉお
かがきぎくぐけげこご
さざしじすずせぜそぞ
ただちぢっつづてでと
どなにぬねのはばぱひ
びぴふぶぷへべぺほぼ
ぽまみむめもゃやゅゆ
ょよらりるれろゎわゐ
ゑをん゛゜ゝゞ
------------------------------
片假名89個(gè) asc值
-23135 -> -23059
unicode 30A0-30FF

ァアィイゥウェエォオ
カガキギクグケゲコゴ
サザシジスズセゼソゾ
タダチヂッツヅテデト
ドナニヌネノハバパヒ
ビピフブプヘベペホボ
ポマミムメモャヤュユ
ョヨラリルレロヮワヰ
ヱヲンヴヵヶーヽヾ
================補(bǔ)充 修改的版本===========================

添加一個(gè)編碼解碼參數(shù)codeType
都使用一個(gè)函數(shù)
使用chr()不直接使用日文字符
這樣~ 夠簡(jiǎn)潔了吧?

疑點(diǎn): 顯示日文是不會(huì)出錯(cuò)的,保存到數(shù)據(jù)庫(kù)也不會(huì)出錯(cuò)
只有SQL使用 like 和 inStr 的時(shí)候 才會(huì)出錯(cuò) 這個(gè)與顯示無(wú)關(guān)!
還有在vbs里使用 inStr(1,str,"aaa",1)這樣按字符搜索也會(huì)錯(cuò)
改為 inStr(lcase(str),"aaa") 就不會(huì)出錯(cuò)

如果一定得用 inStr(1,str,"aaa",1) 字符搜索語(yǔ)法
則一定要在先inStr() 后 jncode() 的順序 否則會(huì)出錯(cuò)

一點(diǎn)問(wèn)題都沒(méi)有! 注意到這幾點(diǎn)絕對(duì)沒(méi)錯(cuò)!

rs("TopicStr")=Jncode(TopicStr,true) 'encode 保存到數(shù)據(jù)庫(kù)的資料
DisplayStr=Jncode(rs("TopicStr"),false) 'uncode    '顯示到頁(yè)面的標(biāo)題

Function Jncode(byVal iStr,codeType)
    if isnull(iStr) or isEmpty(iStr) or iStr="" then
        Jncode=""
        Exit function
    end if
    dim F,i,E
        E=array("Jn0;","Jn1;","Jn2;","Jn3;","Jn4;","Jn5;","Jn6;",_
                "Jn7;","Jn8;","Jn9;","Jn10;","Jn11;","Jn12;","Jn13;",_
                "Jn14;","Jn15;","Jn16;","Jn17;","Jn18;","Jn19;","Jn20;",_
                "Jn21;","Jn22;","Jn23;","Jn24;","Jn25;")
        F=array(chr(-23116),chr(-23124),chr(-23122),chr(-23120),_
                chr(-23118),chr(-23114),chr(-23112),chr(-23110),_
                chr(-23099),chr(-23097),chr(-23095),chr(-23075),_
                chr(-23079),chr(-23081),chr(-23085),chr(-23087),_
                chr(-23052),chr(-23076),chr(-23078),chr(-23082),_
                chr(-23084),chr(-23088),chr(-23102),chr(-23104),_
                chr(-23106),chr(-23108))
    if codyType then
         for i=0 to 25
         iStr=replace(iStr,F(i),E(i))'□
         next
    else
         for i=0 to 25
         iStr=replace(iStr,E(i),F(i))'□
         next
    end if
    Jncode=iStr
End Function

================補(bǔ)充 修改的版本2 改用unicode===========================

添加一個(gè)編碼解碼參數(shù)codeType
都使用一個(gè)函數(shù)
使用chr()不直接使用日文字符
這樣~ 夠簡(jiǎn)潔了吧?

疑點(diǎn): 顯示日文是不會(huì)出錯(cuò)的,保存到數(shù)據(jù)庫(kù)也不會(huì)出錯(cuò)
只有SQL使用 like 和 inStr 的時(shí)候 才會(huì)出錯(cuò) 這個(gè)與顯示無(wú)關(guān)!
還有在vbs里使用 inStr(1,str,"aaa",1)這樣按字符搜索也會(huì)錯(cuò)
改為 inStr(lcase(str),"aaa") 就不會(huì)出錯(cuò)

如果一定得用 inStr(1,str,"aaa",1) 字符搜索語(yǔ)法
則一定要在先inStr() 后 jncode() 的順序 否則會(huì)出錯(cuò)

一點(diǎn)問(wèn)題都沒(méi)有! 注意到這幾點(diǎn)絕對(duì)沒(méi)錯(cuò)!

rs("TopicStr")=Jncode(TopicStr,true) 'encode 保存到數(shù)據(jù)庫(kù)的資料
DisplayStr=Jncode(rs("TopicStr"),false) 'uncode '顯示到頁(yè)面的標(biāo)題

Function Jncode(byVal iStr,codeType)
if isnull(iStr) or isEmpty(iStr) or iStr="" then
Jncode="" : Exit function
end if
dim F,i,E
E=array("Jn0;","Jn1;","Jn2;","Jn3;","Jn4;","Jn5;","Jn6;",_
"Jn7;","Jn8;","Jn9;","Jn10;","Jn11;","Jn12;","Jn13;",_
"Jn14;","Jn15;","Jn16;","Jn17;","Jn18;","Jn19;","Jn20;",_
"Jn21;","Jn22;","Jn23;","Jn24;","Jn25;")
F=array(chrw(12468),chrw(12460),chrw(12462),chrw(12464),_
chrw(12466),chrw(12470),chrw(12472),chrw(12474),_
chrw(12485),chrw(12487),chrw(12489),chrw(12509),_
chrw(12505),chrw(12503),chrw(12499),chrw(12497),_
chrw(12532),chrw(12508),chrw(12506),chrw(12502),_
chrw(12500),chrw(12496),chrw(12482),chrw(12480),_
chrw(12478),chrw(12476))
if codyType then
for i=0 to 25 iStr=replace(iStr,F(i),E(i)) next
else
for i=0 to 25 iStr=replace(iStr,E(i),F(i)) next
end if
Jncode=iStr
End Function

==========================================================================


[page_break]

這是在網(wǎng)上摘抄的,太多,看了還是不曉得解決,后來(lái)又繼續(xù)翻了一把,發(fā)現(xiàn)一個(gè)工具,讓我跌了一下眼鏡,代碼如下:

<%
'檢查有日文片假名的新聞

Server.ScriptTimeout=300
dim conn,str,rs, sql
set conn=server.createobject("adodb.connection")
set rs=server.createobject("adodb.recordset")
str="provider=Microsoft.Jet.OLEDB.4.0; Data Source="+Server.MapPath("data/xsjnews.asa")
conn.open str
sql="select newsid from news"

rs.open sql,conn,1,1
on error resume next
do until rs.eof
 sql="select newsid from news where (title like 'a' or content like 'a') and newsid = "& rs("newsid")
 Err=0
 conn.execute(sql)
 if not Err=0 then
  Response.Write "錯(cuò)誤新聞ID:"
  Response.Write rs("newsid")
  Response.Write "<br>"
  Err=0
  'sql = "delete * from news where newsid ="& rs("newsid")
  'conn.execute(sql)
 end if
 rs.movenext
loop

rs.close
conn.close
response.write "查找完成"
%>