26個日文片假名導致Access搜尋(80040e14/記憶體溢出)的解決辦法

來源:互聯網
上載者:User
access|解決 補充最新修改版,使用Unicode的字元代碼,而不是非unicode(負數值,有時會出錯)代碼

ゴ ガ ギ グ ゲ ザ ジ ズ ヅ デ ド ポ ベ プ ビ パ ヴ ボ ペ ブ ピ バ ヂ ダ ゾ ゼ
當欄位內包含了這26個日文字元任意一個多個時,就會導致在執行SQL語句中包含了
[欄位] like '%aaaaa%' 或 inStr(1,[欄位],'aaaaa',1)>0
這樣的查詢時,毫無道理的出現了
"Microsoft JET Database Engine 錯誤 '80040e14' 記憶體溢出"的錯誤
其他Jet SQL函數命令未作測試,大概與字元搜尋定位匹配相關的都可能出錯

搜尋相關資料得知被微軟工程師證實是Access的bug,可能是文法關係都是微軟的東東
在vbs中 執行inStr(1,日文平假名變數,"aaaaa",1)依然要出現錯誤
Microsoft VBScript 執行階段錯誤 錯誤 '800a0005' 無效的程序呼叫或參數: 'instr'


沒有搜尋,因這幾個字元出現Access的論壇網站搜尋無法進行,何等痛苦
昨天一朋友大叫怪事,他的音樂資料庫無法搜尋了,只有30000條記錄時是好的
毫無疑問,日文片假名是禍根,花幾分鐘把有包含上面的日文替換成"?"搜尋順利恢複
找來論壇程式使用者群最大的動網dvBBS AC版本 7.0SP2 版測試,同樣有這個日文發帖後 導致無法搜尋並且運行時出錯的問題
線上去搜尋 '80040e14' 記憶體溢出" 的錯誤 多的是!

一簡單有效解決辦法:
對這26個字元進行編碼和解碼,可能效率感覺不理想,測試下來問題不大,速度影響不是太大

編碼:

Function Jencode(byVal iStr)
if isnull(iStr) or isEmpty(iStr) then
  Jencode=""
  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))
  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

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))
  Juncode=iStr
for i=0 to 25
  Juncode=replace(Juncode,E(i),F(i))'□
next
End Function

注意,如果直接使用字元不方便(windows還沒裝日文支援),注釋掉的部分提供有 chr(-23804)

..這樣的定義

這樣
1.
表單輸入儲存時,使用Jencode()將這26個字元先編碼再儲存(為什麼是這26個字元,

經過全部測試87個平假名89個片假名最終認定的)

ゴ 即 chr(-23116) 編碼為 Jn1;
2.
顯示時,則使用 Juncode() 函數進行解碼,還原日文片假名顯示
3.
搜尋索引鍵,也要使用 Jencode() 進行編碼後再放入 like裡
where [Topic] like '%Jencode(kewwords)%' 使用
才能保證搜尋的值和編碼過的資料庫欄位內容匹配

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

PS:
也可以使用Regex來改寫上面的兩個函數,或許效率還要更高些
再就是如果 壓根不使用日文,也不需要搜尋日文,則解碼部分可以不用,

儲存資料實直接把這26個片假名字元替換為空白字元或任一字元,比如"□"
拋磚引玉,如果有更本質的真正的好方法,謝分享

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

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

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

================補充 修改的版本===========================

添加一個編碼解碼參數codeType
都使用一個函數
使用chr()不直接使用日文字元
這樣~ 夠簡潔了吧?

疑點: 顯示日文是不會出錯的,儲存到資料庫也不會出錯
只有SQL使用 like 和 inStr 的時候 才會出錯 這個與顯示無關!
還有在vbs裡使用 inStr(1,str,"aaa",1)這樣按字元搜尋也會錯
改為 inStr(lcase(str),"aaa") 就不會出錯

如果一定得用  inStr(1,str,"aaa",1) 字元搜尋文法
則一定要在先inStr() 後 jncode() 的順序 否則會出錯

一點問題都沒有! 注意到這幾點絕對沒錯!

rs("TopicStr")=Jncode(TopicStr,true)  'encode 儲存到資料庫的資料
DisplayStr=Jncode(rs("TopicStr"),false) 'uncode '顯示到頁面的標題

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



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.