Ошибка при обновлении таблицы со столбцом CLOB:ORA-01461

У меня есть таблица в базе данных Oracle следующим образом,

create table test_clob(
id1 number,
clob_col clob);

Если я пытаюсь вставить переменную varchar2 размером более 4000 в столбец CLOB, она вставляется без проблем.

insert into test_clob values (1,rpad('a',32760,'a'));
commit;

Если я пытаюсь обновить столбец CLOB следующим образом, он работает отлично.

update test_clob set clob_col = rpad('b',32760,'b') where id1 = 1;
commit;

Тем не менее, если я пытаюсь запустить оператор обновления следующим образом, это происходит сбой из-за ошибки "ORA-01461: может связать значение LONG только для вставки в столбец LONG".

declare
large_string varchar2(32767) := rpad('c',32760,'c');
begin
update test_clob set clob_col = nvl(large_string,clob_col) where id1 = 1;
commit;
end;

Я подозреваю, что это - функция NVL, которая вызывает проблему. Любая помощь по этому вопросу высоко ценится.

Примечание: я использовал простую таблицу в примере, но на самом деле таблица имеет несколько столбцов, и оператор update должен обновлять много столбцов одновременно.

1 ответ

Решение

На самом деле, rpad('a',32760,'a') при вызове из SQL возвращает только строку 4k, поэтому она работает.

Varchar тип SQL ограничен 4k, поэтому при попытке связать переменную varchar2 32k из pl/sql произойдет сбой (поскольку rpad при вызове из pl/sql вернет 32k).

например:

SQL> select length(rpad('a',32760,'a'))  from dual;

LENGTH(RPAD('A',32760,'A'))
---------------------------
                       4000

он молча ограничивает возврат до 4k для вас. но pl/sql не будет ограничиваться 4k:

SQL> declare
  2  large_string varchar2(32767) := rpad('c',32760,'c');
  3  begin
  4  dbms_output.put_line(length(large_string));
  5  end;
  6  /
32760

Вы должны определить вашу переменную pl/sql как clob и не varchar2(32760):

SQL> create table test_clob(
  2  id1 number,
  3  clob_col clob);

Table created.

SQL> insert into test_clob values (1,rpad('a',32760,'a'));

1 row created.

SQL> select length(clob_col) from test_clob;

LENGTH(CLOB_COL)
----------------
            4000

SQL> commit;

Commit complete.

SQL> declare
  2  large_string clob := rpad('c',32760,'c');
  3  begin
  4  update test_clob set clob_col = nvl(large_string,clob_col) where id1 = 1;
  5  commit;
  6  end;
  7  /

PL/SQL procedure successfully completed.

SQL> select length(clob_col) from test_clob;

LENGTH(CLOB_COL)
----------------
           32760

SQL>
Другие вопросы по тегам