使用嵌套表在 Oracle PL/SQL 中构建动态 SQL

Posted

技术标签:

【中文标题】使用嵌套表在 Oracle PL/SQL 中构建动态 SQL【英文标题】:Build Dynamic SQl in Oracle PL/SQL using Nested Tables 【发布时间】:2016-03-07 11:28:38 【问题描述】:

以下是我正在处理的 pl/sql 代码的一部分。我想生成动态 sql,它查看 i_emp 嵌套表中的值并将员工姓名作为结果返回到 CharArray。下面的代码不起作用,需要帮助修复代码

这只是示例代码,应该使用动态 sql 完成

TYPE NestArray IS TABLE OF VARCHAR2(50);
TYPE CharArray IS TABLE OF VARCHAR2(255) INDEX BY BINARY_INTEGER;

PROCEDURE SAMPLE(i_emp IN NestArray)

v_emp_name CharArray;

v_sql := 'SELECT emp_name FROM emp ';
v_sql  := v_sql || ' WHERE empid IN (SELECT column_value FROM TABLE('||i_emp||'))';

EXECUTE IMMEDIATE v_sql BULK COLLECT INTO v_emp_name;

end;

【问题讨论】:

为什么这需要是动态的?也许如果您解释您的数据是如何配置的,我们可以为您提供更好的解决方案。现在没有理由让这个查询是动态的。 我的代码包含一些条件,基于这些条件将生成类似于下面的 sql IF i_emp_flg = 'Y' THEN v_sql := v_sql || 'AND emp_address = '''||i_emp_address||''''; ELSIF i_emp_flg = 'N' 那么 v_sql := v_sql || 'AND emp_address 为空'; 类型和过程在一个包中? 是的..程序和类型在包中.. 1.您无法在 SQL 中访问包定义的类型。您必须全局或在模式级别 2 定义它们。过程中的 SQL 不知道参数 i_emp 的内容。查询编译器只看到... WHERE empid IN (SELECT column_value FROM TABLE('NestArray'))...。这是类型名,不是参数,也不是值 【参考方案1】:

请看下面的sn-p。它将描述解决方案。希望对你有帮助

--Create schema level type object 

CREATE OR REPLACE TYPE NestArray IS TABLE OF VARCHAR2(50);

CREATE OR REPLACE PROCEDURE EMP_BULK(p_empni IN NestArray)
AS
TYPE CharArray
IS
  TABLE OF VARCHAR2(255) INDEX BY BINARY_INTEGER;
  v_emp_name CharArray;
--  emp_id NestArray:=NestArray(1,2,3);
--  v_sql LONG;
BEGIN
  SELECT ename BULK COLLECT
  INTO v_emp_name
  FROM emp
  WHERE EMPno IN
    (SELECT COLUMN_VALUE FROM TABLE(p_empni)
    );
END;

EXEC EMP_BULK(NestArray(1,2,3));


----------------------------OUTPUT-------------------------------------------

PL/SQL procedure successfully completed.

【讨论】:

【参考方案2】:

您不需要动态 SQL,嵌套选择可以替换为 MEMBER 运算符。你可以这样做:

CREATE TYPE NestArray IS TABLE OF VARCHAR2(50);
CREATE TYPE CharArray IS TABLE OF VARCHAR2(255);


CREATE OR REPLACE PROCEDURE SAMPLE(
 i_emp   IN  NestArray,
 o_names OUT Chararray
)
IS
BEGIN
  SELECT emp_name
  BULK COLLECT INTO o_names
  FROM   emp
  WHERE  empid MEMBER OF i_emp;
END;
/

【讨论】:

以上是关于使用嵌套表在 Oracle PL/SQL 中构建动态 SQL的主要内容,如果未能解决你的问题,请参考以下文章

在 oracle pl/sql 中如何选择嵌套类型?

Oracle PL/SQL 使用 XMLTABLE 解析 xml 中的嵌套对象

Oracle_PL/SQL 集合

oracle table()函数

Oracle 构建顺序和 PL/SQL 包依赖关系

构建一些动态查询选择并立即在 Oracle PL/SQL 中显示其输出