问题描述
我正在尝试在 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