我有一個NoteDetail表,NoteText的varchar(4000)字段和NoteNumber的number(4,0)。這個想法是,如果一個超過4000個字符的音符進來,它會被分成多個音符,並帶有遞增的NoteNumber條目。ORA-01461:如果輸入字符串> 4000個字符,SUBSTR()是否返回LONG?
執行插入操作的邏輯如下,它在Oracle 10上運行得非常漂亮。最近該應用程序被移動到了Oracle 12c,並且出現錯誤:「ORA-01461:只能將LONG值綁定爲插入一個LONG列「Oracle DBA無法弄清楚爲什麼會發生這種情況。
下面是我的插入代碼的本質;我最好的猜測是,如果傳入的字符串足夠長,那麼即使在分配給varchar2(4000)類型的變量時,SUBSTR()函數也會返回一個長整型。供參考:Oracle SQL Developer指出在插入點(在下面的else塊的循環中)發生錯誤。
有誰知道如何解決這個問題?
DECLARE
s_incoming_string varchar2(32000);
s_substring_value varchar2(4000);
i_note_iteration number(4,0);
i_note_iterations number(4,0);
i_substr_start number(6,0);
k_NoteId number(19,0);
BEGIN
SELECT noteid_seq.nextval INTO k_NoteId FROM dual;
s_incoming_string := {a 7000 character long note};
i_note_iterations := ceil(length(s_incoming_string)/4000);
IF i_note_iteration = i_note_iterations THEN
--I NEVER GET AN ERROR ON THIS BRANCH!!!
INSERT INTO NoteDetail (NoteId, NoteNumber, NoteText)
VALUES (k_NoteId, 1, s_incoming_string);
ELSE
FOR i_note_iteration IN 1..i_note_iterations
LOOP
i_substr_start := (4000 * (i_note_iteration - 1)) + 1;
IF i_note_iteration = i_note_iterations THEN
--this is the last chunk of text; no need
--to read past the end of the buffer
s_substring_value = SUBSTR(s_incoming_string, i_substr_start);
ELSE
--I ONLY GET AN ERROR if this branch is executed before the insert:
s_substring_value = SUBSTR(s_incoming_string, 4000);
END IF;
INSERT INTO NoteDetail (NoteId, NoteNumber, NoteText)
VALUES (k_NoteId, i_note_iteration, s_incoming_string);
END LOOP;
END IF;
END;
表模式是:
DCLARE TABLE NoteDetail (
NoteId number(19,0),
NoteNumber number(4,0),
NoteText varchar2(4000)
);
請包括重現問題所需的最短代碼。請在表格中追加結構。現在只有你的註釋,而不是真正的代碼和'insert'語句。 – krokodilko
我添加了模式和更多的代碼。 –
對於投票結束這件事的人們,你至少會解釋爲什麼?我現在只是在職業生涯中第一次遇到甲骨文,我不得不讓這些樣本變得如此通用,所以我不會因泄露公司信息而被解僱。請在這裏休息一下。 –