1

我目前正在使用的 PL-SQL 包有一个很大的问题。

我要做的就是创建一小段代码来执行此操作:

IS函数部分:

l_tabellen_excl DBMS_utility.name_array;

稍后在代码中:

SELECT DISTINCT TABLE_NAME
BULK COLLECT INTO l_tabellen_excl
FROM
ALL_TAB_COLUMNS
WHERE
TABLE_NAME IN ('TAB_1', 'TAB_2');

SELECT最后在语句中使用这个变量:

AND col.table_name NOT IN (SELECT * FROM TABLE (l_tabellen_excl))

我到ORA-22905: cannot access rows from a non-nested table item这里。

我知道我可以只写AND col.table_name NOT IN ('TAB_1','TAB_2'),但我不想在代码的最深坑中硬编码它......使它很难找到并且不太可配置。

我尝试了很多东西:

type array_t is table of varchar2(10);

不工作。我收到一条错误消息,指出我不能在 SELECT 语句中使用本地声明的集合。

我试图将变量强制转换i_tabellen_excl为本地声明的类型 - 就像一种解决方法。但我得到 ORA-00902 - 无效的数据类型。

我试图声明一个 VARCHAR2 包含一个带有逗号分隔表列表的字符串,它似乎正在工作,但它仍然远离一个干净、编写良好、设计良好的代码。

我尝试了其他不值得一提的选项,例如尝试编写函数等。

我在这件事上迷路了,任何想法都可以很好地测试出来。

4

1 回答 1

1

如果要使用TABLE函数,则必须将TYPE创建为OBJECT类型,将其存储在数据库中并使用它创建函数。稍后您可以在 PL/SQL 代码中使用表函数。

否则,按照您的方式,使用NESTED TABLE您将不得不再次循环以引用集合对象。

SET serveroutput ON
DECLARE
type str_typ
IS
  TABLE OF VARCHAR2(200);
  str_sub str_typ := str_typ ();
BEGIN
  SELECT DISTINCT TABLE_NAME BULK COLLECT INTO str_sub FROM ALL_TAB_COLUMNS;
  FOR i IN 1..str_sub.count
  LOOP
    dbms_output.put_line(str_sub(i));
  END LOOP;
END;
/

因此,您不能将其用作数据库对象,因为您必须将类型创建为对象类型,并创建表函数

例如,

创建类型

SQL> CREATE TYPE col_type AS OBJECT (
  2    col_name VARCHAR2(50)
  3  );
  4  /

Type created.

SQL> CREATE TYPE col_sub_type IS TABLE OF col_type;
  2  /

Type created.

建表函数

SQL> CREATE OR REPLACE FUNCTION get_col_tab RETURN col_sub_type AS
  2    l_type  col_sub_type := col_sub_type();
  3  BEGIN
  4    FOR i IN (SELECT DISTINCT TABLE_NAME t_name FROM ALL_TAB_COLUMNS) LOOP
  5      l_type.extend;
  6      l_type(l_type.last) := col_type(i.t_name);
  7    END LOOP;
  8
  9    RETURN l_type;
 10  END;
 11  /

Function created.

测试一下

SELECT *
FROM   TABLE(get_col_tab());
于 2015-10-12T08:49:27.617 回答