首页 > 解决方案 > 如何使用 Execute Immediate 语句嵌套在 Execute Immediate 中

问题描述

我有一个固定的执行即时叙述。里面的sql_text只会带一个参数做一个简单的语法查询

例子

EXECUTE IMMEDIATE sql_text USING SN RETURNING INTO MSG;

sql_text 是可以交替使用的搜索语句

sql_txt = 'select count(1) from productDetails  where ID = :parameter1'

本来EXECUTE IMMEDIATE只会带一个参数来执行sql_text。这次我想引入多个参数来执行sql_text,而不影响现有的只有一个参数的sql_text操作。

因此,许多尝试都失败了。错误的SQL如下

DECLARE
    SQL_TEXT VARCHAR2(1000);
    MSG VARCHAR2(500);
    SN VARCHAR2(500) := parameter1/parameter2;
BEGIN

   sql_text := '
   DECLARE
   parameters VARCHAR2(50);
   parameter1 VARCHAR2(50);
   parameter2 VARCHAR2(50);
   sql_txt VARCHAR2(1000);
   BEGIN
      parameters := :SN;
      parameter1 := substr(parameters,0,10);
      parameter2 := substr(parameters,11,10);
      
      sql_txt = ''select count(1) from productDetails  where ID = :parameter1
      AND NUMBER = :parameter2''
      EXECUTE IMMEDIATE sql_txt USING parameter1 RETURNING INTO MSG;
   END;'; 
   
    EXECUTE IMMEDIATE sql_text USING SN RETURNING INTO MSG;
    DBMS_OUTPUT.put_line(MSG);
END;

我试图将多个参数放入一个参数中。

SN VARCHAR2(500) := parameter1/parameter2;

从sql_text中取出参数并使用

 parameters := :SN;
      parameter1 := substr(parameters,0,10);
      parameter2 := substr(parameters,11,10);

它不断尝试并失败

数据库版本:oracle database 19c

请求帮忙

谢谢

标签: oraclestored-proceduresplsqldynamic-sqloracle19c

解决方案


您的“错误”SQL 有几个问题:

  1. 分配给 的末尾缺少一个分号sql_text

  2. 在同一语句中,NUMBER除非被引用,否则它不是 Oracle 中的有效标识符。

  3. 的初始化SN需要在文本周围加上撇号。

所以作业sql_text应该读

sql_txt := ''select count(1) from productDetails  where ID = :parameter1
          AND "NUMBER" = :parameter2'';

所以你的块应该是

DECLARE
    SQL_TEXT VARCHAR2(1000);
    MSG VARCHAR2(500);
    SN VARCHAR2(500) := 'parameter1/parameter2';
BEGIN

   sql_text := '
   DECLARE
   parameters VARCHAR2(50);
   parameter1 VARCHAR2(50);
   parameter2 VARCHAR2(50);
   sql_txt VARCHAR2(1000);
   BEGIN
      parameters := :SN;
      parameter1 := substr(parameters,0,10);
      parameter2 := substr(parameters,11,10);
      
      sql_txt = ''select count(1) from productDetails  where ID = :parameter1
      AND "NUMBER" = :parameter2'';
      EXECUTE IMMEDIATE sql_txt USING parameter1 RETURNING INTO MSG;
   END;'; 
   
    EXECUTE IMMEDIATE sql_text USING SN RETURNING INTO MSG;
    DBMS_OUTPUT.put_line(MSG);
END;

但是,可以通过使用以下方法大大简化上述内容:

SELECT COUNT(*)
  INTO MSG
  FROM PRODUCTDETAILS
  WHERE ID = (SELECT REGEXP_SUBSTR(SN, '[^/]+', 1, 1) FROM DUAL) AND
        "NUMBER" = (SELECT REGEXP_SUBSTR(SN, '[^/]+', 1, 2) FROM DUAL);

代替嵌入式动态 PL/SQL 块。所以如果我们创建PRODUCTDETAILS使用

CREATE TABLE PRODUCTDETAILS(ID, "NUMBER", OTHER_FIELD) AS
  SELECT 'parameter1', 'parameter2', 'DATA1' FROM DUAL UNION ALL
  SELECT 'parameter1', 'parameter2', 'DATA2' FROM DUAL UNION ALL
  SELECT 'parameter2', 'parameter3', 'DATA3' FROM DUAL UNION ALL
  SELECT 'parameter3', 'parameter4', 'DATA4' FROM DUAL UNION ALL
  SELECT 'parameter1', 'parameter2', 'DATA5' FROM DUAL UNION ALL
  SELECT 'parameter4', 'parameter2', 'DATA6' FROM DUAL UNION ALL
  SELECT 'parameter5', 'parameter6', 'DATA7' FROM DUAL

上述 SQL 将正确返回'3'到 MSG。

db<>在这里摆弄


推荐阅读