ORA-00911: 無效字元 解決
今天幫同事調一個預存程序。預存程序比較長,問題出現在類似下面的一段代碼上。
BEGIN
EXECUTE IMMEDIATE 'UPDATE '|| v_table_name || ' SET ' || v_column_name || ' = :column_value WHERE ID = :id'
USING V_COLUMN_VALUE, V_ID;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;
程式添加了異常處理模組,但是捕獲到錯誤後沒有進行進一步處理,因此當執行到預存程序這一部分時,程式沒有執行UPDATE操作,也沒有報錯。
首先,檢查了UPDATE語句,似乎沒有什麼問題。於是在EXCEPTION模組中將SQLCODE和SQLERRM列印處理。
運行後得到的錯誤是:ORA-00911: 無效字元。
於是懷疑是傳遞的參數有問題,檢查了v_table_name、v_column_name、V_COLUMN_VALUE和V_ID的值都沒有問題。
只好將產生的UPDATE語句列印出來。檢查了一下,也沒有發現任何問題。
感覺十分奇怪,於是查了查Oracle的Error Reference:
ORA-00911 invalid character
Cause: Special characters are valid only in certain places. If special characters other than $, _, and # are used in a name and the name is not enclosed in double quotation marks ("), this message will be issued. One exception to this rule is for database names; in this case, double quotes are stripped out and ignored.
Action: Remove the invalid character from the statement or enclose the object name in double quotation marks.
似乎看上去是列名或表名中包含了不正確的欄位,又仔細檢查了一遍了產生的UPDATE語句的表名和列名,都是很平常的字母。
V_COLUMN_VALUE是個字串,其中包含中文,會不會是由於當前環境對中文支援有問題。換了個環境測試,也沒有問題。
仔細檢查了資料庫中的欄位名和表名,確認不是以小寫格式存放的。
又檢查了一般輸入的四個參數,而且檢查了它們的長度,已經是否存在不可見的字元。仍然沒有任何收穫。
不使用綁定變數,將四個參數都傳入到字串中,拼成完成的UPDATE語句。然後放到SQLPLUS中執行。居然仍然報錯。
這時的UPDATE語句已經簡單到下面的格式,仍然在報錯。
SQL> UPDATE T SET NAME = '中文and1234' WHERE ID = 1;
UPDATE T SET NAME = '中文and1234' WHERE ID = 1
*
ERROR 位於第 1 行:
ORA-00911: 無效字元
最後終於發現,原來第一個等號“=”被同事敲成了中文的等號了。
鬱悶,我們兩個人調了將近一個小時,居然是這個錯誤。