Как записать большой CLOB в таблицу? Ошибка: String literal too long
Есть процедура, которая записывает данные в таблицу.
Пример процедуры:
procedure pSave(sRefer in varchar2,
cMsgQueue in clob) is
begin
insert into table1 (REFER, MSG)
values(sRefer, cMsgQueue);
end;
В значении параметра cMsgQueue передается CLOB, у которого кол-во символов 204017 (размер).
При запуске процедуры получаю ошибку:
string literal too long
Как можно записать большой CLOB в таблицу одним sRefer?
Если передавать маленькие куски, то процедура отрабатывает без ошибки.
Ответы (1 шт):
Обе ошибки, в SQL и PL/SQL соответственно:
ORA-01704: string literal too long
PLS-00172: string literal too long
Говорят о превышении лимита для символьного литерала, то есть колличества символов (ед.изм. в байтах) между одиночными кавычками '' (обычно 4000 в SQL и 32767 в PL/SQL).
Ошибка возникает при инициализации параметра для передачи в процедуру символьным литералом с превышением длины, то есть до того, как процедура собственно будет вызвана.
Возможные решения, добавлять в CLOB по частям, либо процедурой dbms_lob.append, либо конкантенацией:
declare
c clob := '123';
begin
for i in 1..3 loop
dbms_lob.append (c, rpad ('A', 32767, 'A')); end loop;
pSave ('ref1', c);
end;
/
declare
longstring1 varchar2 (32767) := 'AAA<всего 32767 символов>AAA';
longstring2 varchar2 (32767) := 'AAA<всего 32767 символов>AAA';
begin
pSave ('ref2', longstring1||longstring2);
end;
/
Небольшой обзор, что работает, а что нет, на db<>fiddle.
Следует учесть, что инструменты могут накладывать свои ограничения на длину вводимых литералов. Например, SQL*Plus считает, что и 3000 уже достаточно:
$ sqlplus -l user/pass@server/db1 <<EOF
declare var varchar(32767) := '$(printf 'A%.0s' {1..4000})'; begin null; end;
/
EOF
SQL> SP2-0341:
line overflow during variable substitution (>3000 characters at line 1)