【问题标题】:How to use a string as a variable in NOT IN clause?如何在 NOT IN 子句中使用字符串作为变量?
【发布时间】:2015-10-09 14:08:33
【问题描述】:

我将从我目前正在使用的 SQL 脚本中为您提供两段代码,但它们就足够了。 首先,我声明一个变量:

FUNCTION Run
( i_PlafId  IN INTEGER
)
RETURN INTEGER
IS

l_tables_excl VARCHAR2(256) := 'TABLE_1,TABLE_2';

以后我想在某个地方使用它,像这样:

AND cos.table_name NOT IN l_tables_excl

这将是:

AND cos.table_name NOT IN ('TABLE_1', 'TABLE_2')

没有办法进行试验,因为运行这个 Oracle 包大约需要 2 天...

提前致谢!

【问题讨论】:

标签: oracle plsql


【解决方案1】:

处理这样的值列表的最佳方法是使用数组:

create or replace type t_table_list as table of varchar2(50);

FUNCTION Run
( i_PlafId  IN INTEGER
)
RETURN INTEGER
IS

l_tables_excl t_table_list := t_table_list('TABLE_1','TABLE_2');
...
AND cos.table_name NOT IN (select * from table(l_tables_excl))

您应该注意,该类型必须创建为数据库对象,而不是在包中声明。

【讨论】:

  • 看起来很不错,但我得到Error(240,34): PLS-00642: local collection types not allowed in SQL statements...
  • 该类型必须创建为数据库对象才能在 SQL 中使用。这意味着它必须有自己的create or replace,而不是仅仅在 PL/SQL 中声明。如果您可以在 ALL_TYPES 中看到该类型,那么它的创建方式是正确的。
【解决方案2】:

选项 A - 使用 LIKE

您可以通过LIKE 来查看表名是否在字符串中。这是否有效取决于您的表名的相似程度。

/* Returns true if table name isn't a substring of l_tables.excl */
AND l_tables_excl NOT LIKE '%' || cos.table_name || '%'

选项 B - 将字符串拆分为表格

或者您可以将字符串拆分为表格,然后您就可以使用NOT IN。这有点困难,所以我只是给你参考:

测试说明:如果运行你的包需要两天时间,你可能想找到一种只做部分工作的方法。就像它处理 1000 行一样,添加一个变量来告诉它只处理 100 行,这样它就会完成。你真的需要能够测试,两天太长了。

【讨论】:

    【解决方案3】:

    您可以使用 REGEXP_LIKE 函数来模拟 in 子句:

    WHERE NOT REGEXP_LIKE(l_tables_excl, '(^|,)'||cos.table_name||'(,|$)')
    

    【讨论】:

      猜你喜欢
      • 2019-08-10
      • 1970-01-01
      • 2016-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多