2

这是我的线索……我在使用 oracle 11g。搜索了很多,但没有找到。

我需要执行 DML 操作,其中可以包含 > 4k 个字符的数据。

如果我直接在 oracle 中使用 sql 块,就像下一个一样,一切正常

declare 
  txtV varchar2(32000);
BEGIN 
  txtV:= 'MORE THAN 4k CHARS, here only few for readability' ; 
  Update FD_FILTERDEF 
     set SQLFILTER = txtV 
   where id='blabla';  
END;

但!!!如果我使用合并语句,它会给我错误ORA-01461

declare 
  txtV varchar2(32000);
BEGIN 
  txtV:= '' ; 
  MERGE INTO FD_FILTERDEF A 
        USING ( select  txtV C0 
                  from dual) ST 
           ON (A.CODE = 'bla bla') 
  WHEN MATCHED THEN 
    Update set A.SQLFILTER = st.C0  
  WHEN NOT MATCHED THEN 
    insert (CODE  ,SQLFILTER ) 
      values ('bla bla'  , ST.C0  );  
END; 

如果有一些提示将不胜感激:)

4

4 回答 4

1

用这个:

create table fd_filterdef
( code varchar2(10) primary key
, sqlfilter clob );

declare
    txtv varchar2(32000);
begin
    txtv := rpad('select statement, really really long', 5000, ' etc');

    merge into fd_filterdef a
    using (select 'bla bla' as code from dual) st
    on (a.code = st.code)
    when matched then
        update set a.sqlfilter = txtv
    when not matched then
        insert (code, sqlfilter)
        values (st.code,txtv);
end;
/

select code, length(sqlfilter) from fd_filterdef;

CODE       LENGTH(SQLFILTER)
---------- -----------------
bla bla                 5000

从 dual 中选择 long 变量会隐式将其转换varchar2为 12c 之前的 SQL,该 SQL 最多只能容纳 4000 个字节。

于 2016-07-19T17:10:21.427 回答
1

你不能选择 varchar2 超过 4k https://docs.oracle.com/cd/B28359_01/server.111/b28320/limits001.htm

看你的代码

 select  txtV C0 from dual

但在 oracle 12c 中,您可以 https://docs.oracle.com/database/121/SQLRF/sql_elements001.htm#SQLRF30020

于 2016-07-19T17:12:03.370 回答
0

@William ...好吧,也许我在写脚本时有点困惑。我对“pk 错误”的原因感到惊讶,因为我的脚本如下所示。我打算根本不使用“选择”语句,只是在插入和更新中传递代码(如下),因为我以编程方式构建查询并用占位符替换值....这样,没有pk错误一点也不。当然,在您的示例中,原因插入使用了查询中的代码,但在更新中使用了值“TESTCODE”......所以它正在搜索(和更新)代码,但插入另一个:P 抱歉我的错 :)

declare 
  txtV varchar2(32000);
BEGIN 
  txtV:= '5000 chars ....';
  MERGE INTO FD_FILTERDEF A 
        USING ( select  'not used' Code from dual) ST 
           ON (A.CODE = 'TESTCODE') 
  WHEN MATCHED THEN 
    Update set A.SQLFILTER = txtV   --<<<< LOOK HERE I USE DIRECTLY THE VARIABLE DELCARED, NOT THE ONE FROM SELECT STMT 
  WHEN NOT MATCHED THEN 
    insert (CODE  ,SQLFILTER ) 
      values ('TESTCODE'  , txtV  );  
END;
于 2016-07-25T10:06:24.083 回答
0

@William 很好的提示,这是您发布的作品。

但我很确定我已经测试了一种非常相似的语法,其中唯一的区别在于 select 语句,你提供的那个工作正常......以下一个会引发错误:

declare 
  txtV varchar2(32000);
BEGIN 
  txtV:= '5000 chars ....';
  MERGE INTO FD_FILTERDEF A 
        USING ( select  'not used' Code from dual) ST 
           ON (A.CODE = 'TESTCODE') 
  WHEN MATCHED THEN 
    Update set A.SQLFILTER = txtV   --<<<< LOOK HERE I USE DIRECTLY THE VARIABLE DELCARED, NOT THE ONE FROM SELECT STMT 
  WHEN NOT MATCHED THEN 
    insert (CODE  ,SQLFILTER ) 
      values (st.code  , txtV  );  
END;
于 2016-07-21T09:21:19.533 回答