ORA-01461的解決過程~~
近日生產庫中的一個過程報出了ora-1461的錯誤,雖然錯誤實際處理起來非常簡單,但解決過程中與yangtingkun老大就該問題思想火花的碰撞還是讓我頗有收益。
建立一個最簡單的示例演示一下錯誤的觸發:
SQL> CREATE TABLE T_VARCHAR (ID VARCHAR2(10));
Table created
SQL> DECLARE
2 V_STR VARCHAR2(10000) := lpad('a',10000,'a');
3 BEGIN
4 INSERT INTO T_VARCHAR VALUES (SUBSTR(V_STR,1,10));
5 END;
6 /
DECLARE
V_STR VARCHAR2(10000) := lpad('a',10000,'a');
BEGIN
INSERT INTO T_VARCHAR VALUES (SUBSTR(V_STR,1,10));
END;
ORA-01461: can bind a LONG value only for insert into a LONG column
ORA-06512: at line 5
一條最簡單的insert居然報錯了,有意思吧,是因為v_str的值超長?不應該啊,因為我們在insert時是執行了substr的,甚至說將substr改成這樣,還是會報錯:
SQL> DECLARE
2 V_STR VARCHAR2(10000) := lpad('a',10000,'a');
3 BEGIN
4 INSERT INTO T_VARCHAR VALUES (SUBSTR(V_STR,1,1));
5 END;
6 /
DECLARE
V_STR VARCHAR2(10000) := lpad('a',10000,'a');
BEGIN
INSERT INTO T_VARCHAR VALUES (SUBSTR(V_STR,1,1));
END;
ORA-01461: can bind a LONG value only for insert into a LONG column
ORA-06512: at line 5
顯然不會是因為多位元組擷取問題導致的插入失敗,而且如果是插入字元超出列長度的話,應該是報這個錯誤才對:
SQL> insert into t_varchar values (lpad('a',11,'a'));
insert into t_varchar values (lpad('a',11,'a'))
ORA-12899: value too large for column "TEST"."T_VARCHAR"."ID" (actual: 11, maximum: 10)
下面,改一下我們的插入語句:
SQL> DECLARE
2 V_STR VARCHAR2(10000) := lpad('a',10000,'a');
3 BEGIN
4 V_STR := SUBSTR(V_STR,1,10);
5 INSERT INTO T_VARCHAR VALUES (V_STR);
6 END;
7 /
PL/SQL procedure successfully completed
這下成功了,似乎有點兒頭緒,再改一下:
SQL> DECLARE
2 V_STR CHAR(4000) := 'a';
3 BEGIN
4 INSERT INTO T_CHAR VALUES (SUBSTR(V_STR,1,10));
5 END;
6 /
PL/SQL procedure successfully completed
也成功了。ok,基本確認問題所在,總結如下:
字元型別在pl/sql中做為變數存大,最大可支援32767個位元組,但在sql中通常只能夠支援到4000位元組(char/nchar為2000),因此如果宣告的變數長度超出了sql中型別長度,並且變數實際值也超出型別可接受最大值時,就會觸發ORA-01461錯誤,解決方法自然相當簡單,只要在插入/更新之前擷取字元長度到符合要求的長度就可以了。
另外,這裡需要注意,一定要在插入/更新之前擷取,而不要在插入/更新時substr,如例:
SQL> DECLARE
2 V_STR VARCHAR2(10000) := lpad('a',10000,'a');
3 BEGIN
4 INSERT INTO T_VARCHAR VALUES (SUBSTR(V_STR,1,10));
5 END;
6 /
DECLARE
V_STR VARCHAR2(10000) := lpad('a',10000,'a');
BEGIN
INSERT INTO T_VARCHAR VALUES (SUBSTR(V_STR,1,10));
END;
ORA-01461: can bind a LONG value only for insert into a LONG column
ORA-06512: at line 5
這樣也仍然是會出錯的,這應該是由於pl/sql引擎在編譯時對變數長度的判斷先於substr進行,因此不等執行就先報錯了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7607759/viewspace-521189/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORA-01461解決過程
- kettle 報ORA-01461 解決辦法
- crontab失敗的解決過程
- 一個 ExpressionChangedAfterItHasBeenCheckedError 錯誤的解決過程ExpressError
- ora-01536的解決過程
- 記錄一個前端bug的解決過程前端
- 一個lua問題解決過程
- 儲存過程效能低的解決方法之一儲存過程
- 一次線上問題的排查解決過程
- 一次sqlldr匯入慢的解決過程SQL
- 伺服器硬碟掉了兩塊的解決過程伺服器硬碟
- Oracle儲存過程編譯卡死的解決方法Oracle儲存過程編譯
- ORA-600(17069)錯誤的解決過程
- ORA-2049錯誤解決過程
- TNS-12500解決過程(zt)
- munium學習過程中問題解決
- 運維必備-解決鎖問題的全過程運維
- 記一次 Composer 問題的解決過程!!
- sql server資料庫附加錯誤的解決過程SQLServer資料庫
- 用wrap加密一個package異常的解決過程加密Package
- Windows 7安裝過程當機的解決辦法Windows
- 【mysql】配置MySQL,解決安裝過程中的問題MySql
- Java 記憶體洩露的理解與解決過程Java記憶體洩露
- 一次library cache pin故障的解決過程
- 解決儲存過程擷取錯誤的問題儲存過程
- 儲存過程被鎖無法編譯的解決儲存過程編譯
- ERP運用過程中的風險解決思路(轉)
- 一次RAC節點當機的解決過程
- 遊戲,一個有樂趣的、解決問題的過程遊戲
- Oracle 編譯儲存過程卡死解決方法Oracle編譯儲存過程
- 分享:MySQL資料庫崩潰解決過程MySql資料庫
- 【故障診斷】cr塊slot notfound解決過程
- 安裝sysbench過程報錯,解決辦法
- enq: HW - contention診斷及解決過程ENQ
- oracle儲存過程!解決網友問題Oracle儲存過程
- Data Pump Import速度問題之解決過程Import
- httpd使用systemctl啟動超時解決過程httpd
- ORA-01461: 僅可以為插入 LONG 列的 LONG 值賦值”解決辦法賦值