您收到 ORA-01704 是因为您的字符串文字超过 4000 个字节,这是 SQL 调用中字符串文字的大小限制。在 PL/SQL 中,限制为 32k,因此如果您的所有值都小于该值,您可以将它们分配给 PL/SQL 变量并将其用于插入:
DECLARE
newId NUMBER(38,0) := &1;
newDescription varchar2(32767); -- or clob
BEGIN
newDescription := 'LARGE CLOB WHICH PRODUCES EXCEPTION';
Insert into FOO ("ID", "DESCRIPTION")
values (newId+1, newDescription);
newDescription := 'ANOTHER LARGE CLOB WHICH PRODUCES EXCEPTION';
Insert into FOO ("ID", "DESCRIPTION")
values (newId+1, newDescription);
...
END;
/
如果任何值超过 32k,您将需要一个 PL/SQL CLOB 变量,并且需要通过附加短 (
使用多个插入语句可能不是最好的方法。您也许可以使用 SQL*Loader 或外部表来更简单地加载数据。或者您可以使用utl_file 读取值,例如到同一个 PL/SQL 变量中,然后在循环中插入 - 这将减少代码并且更易于维护。
您还可以使用集合来保存字符串值:
DECLARE
TYPE stringTab IS table of varchar2(32767); -- or clob
newDescriptions stringTab := new stringTab();
BEGIN
newDescriptions.extend;
newDescriptions(newDescriptions.last) := 'LARGE CLOB WHICH PRODUCES EXCEPTION';
newDescriptions.extend;
newDescriptions(newDescriptions.last) := 'ANOTHER LARGE CLOB WHICH PRODUCES EXCEPTION';
forall i in newDescriptions.first..newDescriptions.last
insert into FOO ("ID", "DESCRIPTION")
values (&1 + 1, newDescriptions(i));
END;
/
...这将是性能和(可能)可读性之间的权衡,与集合的内存使用情况。如果这对您的情况可行,您可以将其填充到块中,或者再次将值从文件中读取到集合中。
您仍然可以通过对现有表的查询来生成它,例如:
set pages 0
set lines 32767
set long 32767
set define off
select 'DECLARE' || chr(10)
|| ' newId NUMBER(38,0) := &1;' || chr(10)
|| ' newDescription varchar2(32767);' || chr(10)
|| 'BEGIN'
from dual;
select ' newDescription := q''[' || description || ']'';' || chr(10)
|| ' newId := newId + 1;' || chr(10)
|| ' insert into FOO ("ID", "DESCRIPTION") values (newId, newDescription);' || chr(10)
from foo;
select 'END;' || chr(10)
|| '/' || chr(10)
|| 'exit'
from dual;
set define on
我使用the alternative quoting mechanism 以防您的任何字符串值包含单引号,但您需要选择合适的引号分隔符。再次假设您的 CLOB 值都不超过 32k。
如果你真的想用一个充满插入语句的脚本来做这件事,我也会重新考虑;如果数据无论如何都来自表,那么导出/导入可能更合适。