Ошибка при обновлении таблицы со столбцом 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>