ORA-01461 (with > 4k varchar2) 错误仅在合并语句中。插入或更新工作正常
ORA-01461 (with > 4k varchar2) error Only in merge statement. Insert or update works fine
这是我的线索...
我在 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;
如有提示将不胜感激:)
使用这个:
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 变量会隐式地将其转换为 SQL varchar2
,在 12c 之前它最多只能容纳 4000 个字节。
你不能 select 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
@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;
@William ... 好吧,也许我在写脚本时有点混乱。我对 "pk error" 感到惊讶,因为在我看来我已经按如下方式完成了脚本。我打算完全不使用 "select" 语句,只是在插入和更新中传递代码(如下所示),因为我以编程方式构建查询并用占位符替换值....
这样就完全没有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;
这是我的线索... 我在 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;
如有提示将不胜感激:)
使用这个:
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 变量会隐式地将其转换为 SQL varchar2
,在 12c 之前它最多只能容纳 4000 个字节。
你不能 select 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
@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;
@William ... 好吧,也许我在写脚本时有点混乱。我对 "pk error" 感到惊讶,因为在我看来我已经按如下方式完成了脚本。我打算完全不使用 "select" 语句,只是在插入和更新中传递代码(如下所示),因为我以编程方式构建查询并用占位符替换值.... 这样就完全没有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;