我有一个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
我添加了模式和更多的代码。 –
对于投票结束这件事的人们,你至少会解释为什么?我现在只是在职业生涯中第一次遇到甲骨文,我不得不让这些样本变得如此通用,所以我不会因泄露公司信息而被解雇。请在这里休息一下。 –