有以下查询:
select table_name
from user_tables
where table_name in ('A','B','C','D','E','F');
假设只存在user_tables记录B,C和F,我想检索不存在的值A,D和E.这是一个简单的例子,在现实世界中列表可能很大。
答案 0 :(得分:4)
生成假行的好方法是使用标准集合,例如sys.odcivarchar2list
:
select
tables_to_check.table_name,
case when user_tables.table_name is null then 'No' else 'Yes'end table_exists
from
(
select column_value table_name
from table(sys.odcivarchar2list('does not exist', 'TEST1'))
) tables_to_check
left join user_tables
on tables_to_check.table_name = user_tables.table_name
order by tables_to_check.table_name;
TABLE_NAME TABLE_EXISTS
---------- ------------
TEST1 Yes
does not exist No
答案 1 :(得分:2)
如果你有表1中要检查的所有表的列表,那么你可以使用NOT EXISTS子句
select name
from Table1 T1
where not exists ( select 1 from
user_tables U
where T1.name = U.table_name)
答案 2 :(得分:2)
唯一的方法是通过将NOT EXISTS
字符串转换为值表来使用IN clause
。(CTE)
但这不是一个干净的解决方案。由于IN
子句表达式的最大长度仅为4000
,包括逗号..
WITH MY_STRING(str) AS
(
SELECT q'#'A','B','C','D','E','F'#' FROM DUAL
),
VALUES_TABLE AS
(
SELECT TRIM(BOTH '''' FROM REGEXP_SUBSTR(str,'[^,]+',1,level)) as table_name FROM MY_STRING
CONNECT BY LEVEL <= REGEXP_COUNT(str,',')
)
SELECT ME.* FROM VALUES_TABLE ME
WHERE NOT EXISTS
(SELECT 'X' FROM user_tables u
WHERE u.table_name = ME.table_name);
答案 3 :(得分:0)
你做不到。必须至少将这些值输入临时表以执行所需的操作。 Oracle的IN子句列表也不能很大(即不超过1000个值)。
答案 4 :(得分:0)
您是否仅限于以逗号分隔列表的形式接收这些值?
然后您可以从表B中选择所有
select * from tab1;
------------------
A
B
C
D
E
F
Create or replace procedure proc1 as
cursor c is select col1 from tab1;
r tab1.col1%type;
i number;
begin
open c;
loop
fetch c into r;
exit when c%notfound;
select count(tname) into i from tab where tname = r;
if i = 0 then
v_sql := 'insert into tab2 values ('''||r||''');
execute immediate v_sql;
commit;
end if;
end loop;
close c;
end proc1;
select * from tab2;
------------------
A
D
E
如果这不是一次性的话,那么手头有这个过程会很方便。