我正在使用Oracle,而且我有一个非常大的表。我需要检查是否存在符合某些简单标准的行。使用简单的SQL,最好的方法是什么?
这是我最好的猜测,虽然它可能足够快我的目的,但我很想学习一种规范的方法来基本上在Oracle中使用SQL Server“存在”:
select count(x_id) from x where x.col_a = value_a and x.col_b = value_b;
然后count()将作为另一层中的布尔值返回。重点是我希望Oracle为此查询做最低限度的工作 - 我只需要知道是否有符合条件的行。
是的,这些专栏肯定会被编入索引。
答案 0 :(得分:16)
如果您还使用rownum = 1:
,则使用COUNT(*)即可declare
l_cnt integer;
begin
select count(*)
into l_cnt
from x
where x.col_a = value_a
and x.col_b = value_b
and rownum = 1;
end;
这将始终返回一行,因此无需处理任何NO_DATA_FOUND异常。 l_cnt的值将为0(无行)或1(至少存在1行)。
答案 1 :(得分:7)
我认为使用EXISTS可以提供更自然的答案,而不是尝试使用ROWNUM优化COUNT查询。
让Oracle为您进行ROWNUM优化。
create or replace function is_exists (
p_value_a varchar2,
p_value_b varchar2)
return boolean
is
v_exists varchar2(1 char);
begin
begin
select 'Y' into v_exists from dual
where exists
(select 1 from x where x.col_a = p_value_a and x.col_b = p_value_a);
exception
when no_data_found then
v_exists := null;
end;
return v_exists is not null;
end is_exists;
答案 2 :(得分:5)
SELECT NULL
FROM x
WHERE x.col_a = value_a
AND x.col_b = value_b
AND rownum = 1
COUNT(*)
肯定不是最佳方式,因为它需要计算所有行,而ROWNUM = 1
会在找到第一个匹配行后立即返回。
以下是PL/SQL
代码:
DECLARE
ex INT;
BEGIN
BEGIN
SELECT NULL
INTO ex
FROM dual
WHERE 1 = 1
AND rownum = 1;
DBMS_OUTPUT.put_line('found');
EXCEPTION
WHEN no_data_found THEN
DBMS_OUTPUT.put_line('not found');
END;
END;
答案 3 :(得分:1)
begin
select 'row DOES exist'
into ls_result
from dual
where exists (select null from x where x.col_a = value_a and x.col_b = value_b);
exception
when no_data_found then
ls_result := ' row does NOT exist';
end;