SQLPlus:ORA-01756:引用的字符串未正确终止

时间:2017-02-06 10:26:25

标签: sql oracle sqlplus

我试图在Oracle中使用SQLPlus更新表。我的更新声明如下,但我收到了错误:

UPDATE mytable
   SET mycol =
          '
CREATE OR REPLACE function stg.myfun(i_run_id number, i_rec number default 0) return number as 
begin
 insert into stg.tab (col1,col2,col3,col4,col5,col6,col7)
  select src.col1, src.col2, i_run_id, src.col4,''myval'', src.s1, src.s2 
    from stg.sourcetab src
   order by col1;
 return SQL%ROWCOUNT;
exception WHEN OTHERS THEN
 IF SQLCODE = -1  
  THEN
   if i_rec>15 
   then raise;
   else return stg.myfun(i_run_id, i_rec+1);
   end if;
  ELSE
   raise; 
 end if;
end;
'
where 1 = 1
and gn = 'value';
commit;

错误是:

ERROR:
ORA-01756: quoted string not properly terminated

SP2-0734: unknown command beginning "return SQL..." - rest of line ignored.
SP2-0734: unknown command beginning "exception ..." - rest of line ignored.
SP2-0734: unknown command beginning "IF SQLCODE..." - rest of line ignored.
SP2-0042: unknown command "THEN" - rest of line ignored.
SP2-0044: For a list of known commands enter HELP and to leave enter EXIT.
SP2-0734: unknown command beginning "if i_rec>1..." - rest of line ignored.
SP2-0042: unknown command "then raise" - rest of line ignored.
SP2-0734: unknown command beginning "else retur..." - rest of line ignored.
SP2-0042: unknown command "end if" - rest of line ignored.
SP2-0044: For a list of known commands enter HELP and to leave enter EXIT.
SP2-0042: unknown command "ELSE" - rest of line ignored.
SP2-0042: unknown command "raise" - rest of line ignored.
SP2-0042: unknown command "end if" - rest of line ignored.
SP2-0042: unknown command "end" - rest of line ignored.
SP2-0044: For a list of known commands enter HELP and to leave enter EXIT.
SP2-0042: unknown command "'" - rest of line ignored.
SP2-0734: unknown command beginning "where 1 = ..." - rest of line ignored.
SP2-0734: unknown command beginning "and gn..." - rest of line ignored.

3 个答案:

答案 0 :(得分:2)

一种方法是将语句包装在一个简单的PL / SQL块中:

SQL> begin
  2  UPDATE mytable
  3     SET mycol =
  4            '
  5  CREATE OR REPLACE function stg.myfun(i_run_id number, i_rec number default 0) return number as
  6  begin
  7   insert into stg.tab (col1,col2,col3,col4,col5,col6,col7)
  8    select src.col1, src.col2, i_run_id, src.col4,''myval'', src.s1, src.s2
  9      from stg.sourcetab src
 10     order by col1;
 11   return SQL%ROWCOUNT;
 12  exception WHEN OTHERS THEN
 13   IF SQLCODE = -1
 14    THEN
 15     if i_rec>15
 16     then raise;
 17     else return stg.myfun(i_run_id, i_rec+1);
 18     end if;
 19    ELSE
 20     raise;
 21   end if;
 22  end;
 23  '
 24  where 1 = 1
 25  and gn = 'value';
 26  end;
 27  /

PL/SQL procedure successfully completed.

答案 1 :(得分:1)

由于您特别询问SQL * Plus,因此可以SQL terminator character更改为字符串中未出现的内容,或者完全禁用它,其中任何一个都会停止字符串中行末尾的分号被解释为语句分隔符:

set sqlterminator off

UPDATE mytable
   SET mycol =
          '
CREATE OR REPLACE function stg.myfun(i_run_id number, i_rec number default 0) return number as 
begin
 insert into stg.tab (col1,col2,col3,col4,col5,col6,col7)
  select src.col1, src.col2, i_run_id, src.col4,''myval'', src.s1, src.s2 
    from stg.sourcetab src
   order by col1;
 return SQL%ROWCOUNT;
exception WHEN OTHERS THEN
 IF SQLCODE = -1  
  THEN
   if i_rec>15 
   then raise;
   else return stg.myfun(i_run_id, i_rec+1);
   end if;
  ELSE
   raise; 
 end if;
end;
'
where 1 = 1
and gn = 'value'
/

1 row updated.

set sqlterminator on

commit;

Commit complete.

请注意,更新语句本身必须立即通过新行上的斜杠终止(或者如果您不完全将其关闭,则由指定的字符终止)。我重新启用它以允许分号再次用于提交。

但是,这在SQL Developer中不起作用(至少在4.2中,表示set sqlterminator已过时)或者可能是其他同样困惑的客户端。在PL / SQL块中包装可能是更好的通用解决方案;或者使用绑定变量,但是你也必须仔细分配它们的值。

您还可以使用the alternative quoting mechanism来避免需要转义字符串中的单引号(即''myval''),但这并不会阻止SQL * Plus将尾随分号视为语句分隔符,如果您使用其他任何方法,这将是一个改进。

答案 2 :(得分:-1)

drop table junk;

create table junk( id number(1) not null
        , stmt varchar2(200) )
/

insert into junk values ( 1, null );
commit;

update junk
set stmt = q'[ select ename from emp where ename = 'KING'; ]'
where id = 1
;

commit
;

select * from junk
;

结果

        ID STMT
---------- --------------------------------------------------
         1  select ename from emp where ename = 'KING';