Oracle ORA-01461(带>4k varchar2)错误仅出现在merge语句中。插入或更新工作正常

Oracle ORA-01461(带>4k varchar2)错误仅出现在merge语句中。插入或更新工作正常,oracle,plsql,oracle11g,merge,ora-01461,Oracle,Plsql,Oracle11g,Merge,Ora 01461,这是我的线索。。。 我在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

这是我的线索。。。 我在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;
但是!!! 如果我使用merge语句,它会给出错误ORA-01461

如果您有一些提示,我们将不胜感激:

请使用以下内容:

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中选择长变量会隐式将其强制转换为SQL varchar2,在12c之前,该变量最多只能容纳4000字节。

选择的varchar2不能超过4k

查看您的代码

 select  txtV C0 from dual
但在oracle 12c中,您可以
@William great hint,这是您发布的作品

但是我很确定我测试过一种非常相似的语法,唯一的区别是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;

@威廉。。。好吧,也许我在写剧本的时候有点困惑。我对pk错误感到惊讶,因为在我看来,我已经按照如下方式完成了脚本。我打算完全不使用select语句,只在insert和update中传递代码,如下所示,因为我以编程方式构建查询,并用占位符替换值。。。。 这样,就根本没有pk错误。当然,在您的示例中,在insert中使用的是来自查询的代码,但在update中使用的是值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;

请显示您的表定义fd_filterdef.sqlfilter的类型是什么?可能是clob?FD_FILTERDEF.SQLFILTER是clob列这不完全正确。。。如果我使用变量=“超过4k字符的文本”;然后从dual中选择variable,我没有问题,所以选择一个大于4k的变量显然是允许的。问题不在select语句中,而在merge one语句中。@Sabbe,如果我尝试从双精度中选择v1到v2,其中v1>4k,我得到ORA-01460:至少在11g中请求了未实现或不合理的转换。@William Robertson是的,当然,因为它是varchar2,而不是clob或其他,这是正确的-因此一个解决方案是将textv更改为clob。但是,我们完全不通过SQL查询传递值,从而避免了复杂的负载。您会得到什么错误?我只收到PK冲突,因为更改联接条件会使它尝试添加具有相同代码的新行。PK冲突。。。为什么?如果在ON条件中使用真实PK,则合并不应给出PK冲突错误。无论如何,使用我的第一个非工作版本得到的错误是ORA-01461:只能为插入到长列中绑定一个长值。上面的代码示例给出了PK冲突,因为a.code与文本TESTCODE不匹配,所以使用了when not matched then insert子句。两次执行将尝试插入同一行,在我的示例中,我在代码上定义了一个PK。我不确定这是什么意思。@William是的,你说得对。我错误地认为,使用直接键值,而不从内部选择获取它。。。关于使用。。。。语句,将以同样的方式工作:无论如何,再次感谢你的提示,解决了我的问题。
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;