預存程序|語句 四年前寫的一個內容管理系統,應用在公司內部網上,昨天DBA說其中的SQL語句未使用參數化的調用,導致伺服器負擔加重,資源佔用大。並列出了幾個佔用資源較大的語句,類似如下:
SELECT ART_ID, ART_TITLE, ... FROM USR_NEWS.VIEW_ARTICLE WHERE ART_ISPASSED='Y' and ART_CLASS=4066 ORDER BY ART_PASSTIME DESC
其中where子句中的ART_CLASS的值是先確定後組合好這樣整條sql語句,然後通過ado去執行的。因參數值不同,在伺服器端會產生不同的sql語句,如果有10萬個值,伺服器就會為這10萬條sql語句建立緩衝。DBA說要改為art_class=:V方式(oracle資料庫),我用與訪問預存程序類似的代碼來寫,如下:
dim userid
userid=1234
...
Command1.CommandText = "SELECT * from users where userid=:V"
Command1.Parameters.Append Command1.CreateParameter(":v", , ,,userid)
set rs = Command1.Execute
運行時在CreateParameter語句處有以下出錯提示:
ADODB.Command (0x800A0BB9)
參數類型不正確,或不在可以接受的範圍之內,或與其他參數衝突。
暈死,為什麼預存程序可以,直接sql語句不行呢?
把省略的參數加上,還是不對。
試了幾次,都不行,於是找微軟支援人員,幾經周轉終於解決了。原來通過ADO訪問時sql語句中的參數要用“?”不用“:”“@”,以下為微軟工程師對此問題的小結:
問題描述:
在ASP中,如果通過VBScript調用ADO操作序列化SQL查詢. 您按照.NET的調用方法出現0x800A0BB9錯誤。
解決辦法:
在VB中調用ADO的序列化查詢,您可以參考下面兩篇文章:
How To Invoke a Parameterized ADO Query Using VBA/C++/Java
http://support.microsoft.com/?id=181734
INFO: Visual Basic Accessing an Oracle Database Using ADO
http://support.microsoft.com/?id=176936
需要注意的是,在VBScript中,很多常量沒有定義,比如adInteger, 我們需要用具體的數值代替。對於CreateParameter的詳細說明,請參考:
CreateParameter Method
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmthcreateparam.asp
再次感謝您致電微軟。