Как записать большой 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 шт):

Автор решения: 0xdb

Обе ошибки, в 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)
→ Ссылка