如何更新包含超过 200 万个字符的数据的 clob 列 示例

问题描述

我正在尝试在 PL/sql 中更新长度 > 200 万个字符的 clob 值。我收到错误

字符串文字太长

有什么办法可以解决这个错误吗?

这是我试图用以下内容更新 clob 值的 PL/sql 代码片段:

 DECLARE 
   value clob; 
   clob_field clob;
   fromindex integer;
   offset integer;
   chunks integer;
   eclob clob;
   sql_stmt clob;
BEGIN 
   fromindex := 1;
   offset := 2;  
   clob_field := '<clob_value_with_length_2Million>';
   chunks := 1+(dbms_lob.Getlength(clob_field) / 2);
   value :='';
   
   FOR chunk IN 1 .. chunks LOOP 
     IF ( chunk != 1) THEN
       value := value || ' || ';
     END IF;
     value := value || 'to_clob('''||dbms_lob.Substr(clob_field,offset,fromindex)||''')';
     fromindex := fromindex + 2;
   END LOOP; 
   dbms_output.put_line(value); 
  sql_stmt := 'update mytable
  set sources = ' || value ||' where scenario_id = 1 and entry_index = 1';
  EXECUTE IMMEDIATE sql_stmt;
END; 

我在 clob_field 初始化时遇到错误,这很明显,因为 PL/sql 不允许超过 32k 个字符。所以,我在这里联系,看看我是否可以解决我的问题。

解决方法

如果使用绑定变量,您可以减少所需的代码量并提高代码的性能。如果您每次都尝试构建不同的更新语句,则数据库将需要为每个不同的查询提出一个执行计划。使用绑定变量还无需进行任何 SQL 清理以防止 SQL 注入。

示例

SQL> CREATE TABLE mytable
  2  AS
  3      SELECT 1 AS scenario_id,1 AS entry_index,EMPTY_CLOB () || 'clob1' AS sources FROM DUAL
  4      UNION ALL
  5      SELECT 2 AS scenario_id,2 AS entry_index,EMPTY_CLOB () || 'clob2' AS sources FROM DUAL;

Table created.

SQL> SELECT * FROM mytable;

SCENARIO_ID ENTRY_INDEX SOURCES
----------- ----------- --------------------------------------------------------------------------------
          1           1 clob1
          2           2 clob2

SQL> DECLARE
  2      clob_field      CLOB;
  3      l_scenario_id   NUMBER;
  4      l_entry_index   NUMBER;
  5      sql_stmt        CLOB;
  6  BEGIN
  7      clob_field := '<clob_value_with_length_2Million>';
  8      l_scenario_id := 1;
  9      l_entry_index := 1;
 10
 11      sql_stmt :=
 12          'update mytable set sources = :bind_clob where scenario_id = :scenario and entry_index = :entry';
 13
 14      EXECUTE IMMEDIATE sql_stmt
 15          USING clob_field,l_scenario_id,l_entry_index;
 16  END;
 17  /

PL/SQL procedure successfully completed.

SQL> SELECT * FROM mytable;

SCENARIO_ID ENTRY_INDEX SOURCES
----------- ----------- --------------------------------------------------------------------------------
          1           1 <clob_value_with_length_2Million>
          2           2 clob2