如何在 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
。这有点困难,所以我只是给你参考:
测试说明:如果运行你的包需要两天时间,你可能想找到一种只做部分工作的方法。就像它处理 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()