oracle PL/SQL EXECUTE IMMEDIATE不带SQL、存储过程或函数的块

w46czmvw  于 2023-03-29  发布在  Oracle
关注(0)|答案(2)|浏览(177)

我编写了一个存储过程来从输入术语中去除非字母数字字符,如下所示

CREATE OR REPLACE PROCEDURE CleanTerm(
  p_Cleaned OUT VARCHAR,
  p_Input VARCHAR
)
IS
BEGIN
  p_Cleaned := REGEXP_REPLACE( p_Input, '[^ 0-9A-Za-z]', '');
END;

现在我需要用EXECUTE IMMEDIATE执行这个过程,这并不难,因为我可以将我的局部变量绑定到存储过程中声明的变量

EXECUTE IMMEDIATE 'BEGIN CleanTerm(:1, :2); END;'
  USING l_Cleaned, l_Raw;

有没有一种方法可以在不定义存储过程的情况下做同样的事情?类似于

EXECUTE IMMEDIATE "BEGIN :1 := REGEXP_REPLACE( :2, '[^ 0-9A-Za-z]', ''); END;"
  USING l_Cleaned, l_Raw;

当然,这是行不通的,因为没有输入或输出变量来绑定占位符
PLS-00201:标识符'开始:1:= REGEXP_REPLACE(:2,'[^ 0-9A-Za-z]','');END;'必须声明

jobtbby3

jobtbby31#

DECLARE
  l_Raw     VARCHAR2(4000) := 'something';
  l_Cleaned VARCHAR2(4000);
BEGIN
  EXECUTE IMMEDIATE "BEGIN :1 := REGEXP_REPLACE( :2, '[^ 0-9A-Za-z]', ''); END;"
    USING l_Cleaned, l_Raw;
  -- Do something with l_cleaned
END;
/

失败是因为双引号用于标识符,而你需要单引号,这是字符串文字(并转义字符串中的单引号),并且因为你没有声明OUT绑定变量:

DECLARE
  l_Raw     VARCHAR2(4000) := 'something';
  l_Cleaned VARCHAR2(4000);
BEGIN
  EXECUTE IMMEDIATE 'BEGIN :1 := REGEXP_REPLACE( :2, ''[^ 0-9A-Za-z]'', ''''); END;'
    USING OUT l_Cleaned, l_Raw;
  -- Do something with l_cleaned
END;
/

但是,你可以只使用PL/SQL匿名块而不使用EXECUTE IMMEDIATE,因为你试图执行的东西没有任何动态:

DECLARE
  l_Raw     VARCHAR2(4000) := 'something';
  l_Cleaned VARCHAR2(4000);
BEGIN
  l_Cleaned := REGEXP_REPLACE( l_raw, '[^ 0-9A-Za-z]');
  -- Do something with l_cleaned
END;
/
e7arh2l6

e7arh2l62#

Execute immediate需要PL/SQL;你不能只是“执行”它(例如在SQL级别)。
这里有个例子看看有没有用

SQL> set serveroutput on
SQL>
SQL> declare
  2    l_input  varchar2(20) := 'L#it%/lef"oot';
  3    l_result varchar2(20);
  4  begin
  5    execute immediate q'{select regexp_replace(:b, '[^ 0-9A-Za-z]', '') from dual}'
  6      into l_result using l_input;
  7
  8    dbms_output.put_line('Result = ' || l_result);
  9  end;
 10  /
Result = Litlefoot

PL/SQL procedure successfully completed.

SQL>

或者,在SQL*Plus中运行另一个选项:

SQL> var b varchar2(20)
SQL> exec :b := 'L#it%/lef"oot';

PL/SQL procedure successfully completed.

SQL> var result varchar2(20)
SQL> exec :result := regexp_replace(:b, '[^ 0-9A-Za-z]', '');

PL/SQL procedure successfully completed.

SQL> print result

RESULT
--------------------------------
Litlefoot

SQL>

相关问题