1

次のように、Oracle Databaseにテーブルがあります。

create table test_clob(
id1 number,
clob_col clob);

サイズが 4000 を超える varchar2 変数を 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機能であると思われます。これに関するヘルプは大歓迎です。

注: この例では単純なテーブルを使用していますが、実際にはテーブルには複数の列があり、更新ステートメントは一度に多くの列を更新する必要があります。

4

1 に答える 1

3

実際、rpad('a',32760,'a')SQL から呼び出された場合、4k 文字列しか返されないため、機能します。

SQLのVarchar型は 4k に制限されているため、pl/sql から 32k の varchar2 変数をバインドしようとすると失敗します (pl/sql から呼び出されたときに rpad が 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を NOTとして定義する必要があり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>
于 2013-04-03T16:17:25.287 に答える