如何在 NOT IN 子句中使用字符串作为变量?

Posted

技术标签:

【中文标题】如何在 NOT IN 子句中使用字符串作为变量?【英文标题】:How to use a string as a variable in NOT IN clause? 【发布时间】: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 天...

提前致谢!

【问题讨论】:

Declaration of multiple values in Oracle BIND Variables的可能重复 我想你可以在这里找到答案 - asktom.oracle.com/pls/asktom/… 建议的重复问题与通过绑定变量获取列表有关,在这种情况下,它是 PL/SQL 内部的静态列表,这使得用户定义的类型更实用。 【参考方案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。这有点困难,所以我只是给你参考:

How to split comma separated string and pass to in clause Splitting string into multiple rows in Oracle (SO answer)

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于如何在 NOT IN 子句中使用字符串作为变量?的主要内容,如果未能解决你的问题,请参考以下文章

调整窗口大小时如何将跨度的内容保持在一起(如何在跨度边界处“断字”)?

如何在不知道 sort(XS) 是如何实现的情况下调和这个问题

如何在 Swift 中从 NSData 显示 PDF - 如何将 PDF 保存到文档文件夹 Swift - 如何在 Swift 中通过 WebView 从保存的 NSData 显示 PDF

如何在数据框列表上 lapply() 公式。或如何在数据帧列表上执行 kruskal.test()

如何创建如何在 typeorm 中创建多对多关系,[NestJS]

如何在eclipse上查看源码,如果在idea查看源码待完善