扩展这个问题 - Oracle Delete Rows Matching On Multiple Values,我需要使用两个列表中的DELETE ... WHERE ... IN ...
,但我需要使用由外部语句提供的文本字符串,而不是{{1声明。
例如,我有这两个字符串:
'2810C000000635', '2810C000000636', '2810C000000637'
28006900,28006901,28006902
我希望将它们变成SQL。
SELECT
但是运行这个给了我:
DELETE FROM os_abp_classification WHERE (class_key, uprn) IN ('2810C000000635','2810C000000636','2810C000000637'),(28006900,28006901,28006902)
这被问到Oracle multiple fields in Select IN Parameter - 但是给定的答案对我不起作用:
SQL Error: ORA-00920: invalid relational operator
DELETE FROM os_abp_classification where (class_key, uprn) IN (
SELECT '2810C000000635','2810C000000636','2810C000000637' from DUAL
union
SELECT 28006900,28006901,28006902 from DUAL
)
此类查询的格式是什么?感谢
修改: 我正在尝试复制此功能,但使用“where ... in”格式,因为它更快(在Optimal way to DELETE specified rows from Oracle中发现):
ORA-00913: too many values
答案 0 :(得分:2)
如果您要删除匹配对,则语法为:
DELETE FROM os_abp_classification
WHERE (class_key, uprn) IN (
select '2810C000000635', 28006900 from dual
union all select '2810C000000636', 28006901 from dual
union all select '2810C000000637', 28006902 from dual
union all ...
)
根据字符串的来源,您可以通过将它们分成单独的元素来使其更加通用
delete from os_abp_classification
where (class_key, uprn) in (
with class_keys as (
select level as rn,
regexp_substr('2810C000000635,2810C000000636,2810C000000637',
'[^,]+', 1, level) as class_key
from dual
connect by regexp_substr('2810C000000635,2810C000000636,2810C000000637',
'[^,]+', 1, level) is not null
),
uprns as (
select level as rn,
cast(regexp_substr('28006900,28006901,28006902',
'[^,]+', 1, level) as number) as uprn
from dual
connect by regexp_substr('28006900,28006901,28006902',
'[^,]+', 1, level) is not null
)
select ck.class_key, u.uprn
from class_keys ck
join uprns u on u.rn = ck.rn
);
样本数据的时间越长,但如果你有很多值对,它可能会缩短,你可能会根据你在哪里/如何运行它来绑定字符串值。
子查询使用CTE将每个原始值字符串转换为值列表 - 在第一个字符串中保留为字符串,在第二个字符串中转换为数字。它还为两个集合中的每个结果分配一个伪行号,对于匹配对,它们将是相同的,因此将CTE连接在一起可以为表格准备好in
子句:
SQL Fiddle显示CTE联接的结果,基于此的删除以及之后剩余的行。
如果您已经有值列表,您也可以这样做:
delete from os_abp_classification
where (class_key, uprn) in (
with class_keys as (
select rownum as rn, column_value as class_key
from table(sys.odcivarchar2list('2810C000000635','2810C000000636','2810C000000637'))
),
uprns as (
select rownum as rn, column_value as uprn
from table(sys.odcinumberlist(28006900,28006901,28006902))
)
select ck.class_key, u.uprn
from class_keys ck
join uprns u on u.rn = ck.rn
);
...但在没有明确rownum
的情况下依赖order by
是有风险的;它looks OK here但可能无法保证可以正常工作,即使它现在可以正常工作,也可能在将来中断。 odcivarchar2list
is defined为vararry
,这是一个有序集。我想Tom Kyte sort of implies it's OK too。但即便如此,我也要小心使用它。 (有足够的警告吗?)