Sql 检查行是否存在的最快方法

Sql 检查行是否存在的最快方法,sql,oracle,plsql,Sql,Oracle,Plsql,在将select SOMETHING转换为v_SOMETHING之前,我想知道我的查询是否返回一行 以下是一个很好的方法,但如果行存在,则需要两个选择: select count(1) into isRowExists from PERSON where CONDITION='Something'; if (isRowExists > 0) then select NAME into v_name from PERSON where CONDITION='Something';

在将select SOMETHING转换为v_SOMETHING之前,我想知道我的查询是否返回一行

以下是一个很好的方法,但如果行存在,则需要两个选择:

select count(1) into isRowExists from PERSON where CONDITION='Something';

if (isRowExists > 0) then
    select NAME into v_name from PERSON where CONDITION='Something';
else
    raise name_not_found;
end if;

select count(1) into isRowExists from CAR where CONDITION='Something';

if (isRowExists > 0) then
    select MODEL into v_model from CAR where CONDITION='Something';
else
    raise model_not_found;
end if;
或者类似的:

select NAME into v_name from PERSON where CONDITION='Something';

select MODEL into v_model from CAR where CONDITION='Something';

exception
    when no_data_found then
        --do_something
但是用这种方法,我不知道问题是人还是车

还有其他解决办法吗?像向异常发送参数一样?

您可以执行以下操作:

BEGIN
    BEGIN
        select NAME into v_name from PERSON where CONDITION='Something';
    exception
        when no_data_found then
        --do_something
    END;

    BEGIN
        select MODEL into v_model from CAR where CONDITION='Something';
    exception
        when no_data_found then
            --do_something
    END;
END;
/

对于第二种方法,您只需将每个方法包装在开始/结束块中:


如果名称不为null,则可以尝试以下操作:

select (select NAME from PERSON where CONDITION='Something') into v_name 
from dual;

if v_name is null then 
...

我不会说捕捉未找到的数据是最快的方法。这要看情况而定。有时最好先进行计数,然后再提取。计数的工作速度比检索数据快,所以如果一行不存在的概率很高,计数将更有益。Oracle使用了一些缓存机制,因此第二个查询在相同的位置执行得更快。

您可以将查询参数化,这将花费您1次选择查询,如

@tablename varchar,
@conditionparameter varchar,

select count(1) into isRowExists from tablename where CONDITION='+conditionparameter+' ;
if(@tablename ='PERSON ' and isRowExists > 0)

select NAME into v_name from PERSON where CONDITION='Something';

elseif (@tablename ='CAR' and isRowExists > 0)

select MODEL into v_model from CAR where CONDITION='Something';

else
raise name_not_found;
end if;

这是一个普遍的想法,您可以进一步优化上述查询。

还有一个解决方案可以避免异常:

declare
  client_name varchar2(100);
  model_name varchar2(100);

  cursor clients (p_id number) is
    select client_name from client_table where client_id = p_id;

  cursor models (p_id number) is
    select model_name from model_table where model_id = p_id;

begin
  -- variant 1
  for i in clients(123) loop
    client_name := i.client_name;
    exit;
  end loop;

  -- variant 2
  open models(456);
  fetch models into model_name;

  -- if you need to process "no data found" situation: 
  if models%notfound then
     <do something>
  end;
end;
合并 给出了Oracle的一个示例

在不存在的地方插入 我不确定这是否适用于Oracle,我相信它适用于MySQL和PostgreSQL等一般SQL关系型数据库

INSERT INTO v_name(name) 
   SELECT name FROM person 
   WHERE NOT EXISTS (
      SELECT 1 FROM person WHERE <name/condition> = <value>
   ); 

-- UPDATE ...; -- Add UPDATE statement here to complete an UPSERT query

请说明否决投票的原因:

在未找到数据时使用,但有两个单独的例外情况blocks@6ton有没有示例?为什么要在从行中检索值之前检查行的存在性?根据定义,如果查询未能返回行,则该行不存在。如果添加且ROWNUM=1,则如果有多行符合WHERE条件,则此解决方案也将起作用。这是SQL Server答案。问题上的标签明确指出这是一个Oracle问题。但这需要可重复读取,因此您需要在
INSERT INTO v_name(name) 
   SELECT name FROM person 
   WHERE NOT EXISTS (
      SELECT 1 FROM person WHERE <name/condition> = <value>
   ); 

-- UPDATE ...; -- Add UPDATE statement here to complete an UPSERT query