【问题标题】:Fastest way to check if row exist检查行是否存在的最快方法
【发布时间】:2014-11-14 14:24:23
【问题描述】:

select SOMETHING into v_something 之前,我想知道我的查询是否返回一行。

这是一个很好的方法,但如果该行存在,则需要花费两个 select

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

但是用这个方法,不知道问题是出自PERSON还是CAR...

还有其他解决方案吗?就像向exception 发送参数一样?

【问题讨论】:

  • 当 no_data_found 与 2 个单独的异常块一起使用时
  • @6ton 你有例子吗?
  • 为什么要在从行中检索值之前检查行是否存在?根据定义,如果您的查询未能返回一行,则该行不存在。

标签: sql oracle plsql


【解决方案1】:

你可以这样做:

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;
/

【讨论】:

【解决方案2】:

对于第二种方法,您可以将每个方法包装在 begin/end 块中:

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;

【讨论】:

  • 如果您添加and ROWNUM = 1,那么如果有多个满足WHERE 标准的行,此解决方案也将起作用。
【解决方案3】:

如果名称不为空,你可以试试这个:

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

if v_name is null then 
...

我不会说捕捉 NO_DATA_FOUND 是最快的方法。这真的取决于。有时最好先执行计数然后获取。 COUNT 的工作速度比检索数据更快,因此如果行不存在的可能性很高,则 COUNT 会更有益。并且 Oracle 使用了一些缓存机制,因此具有相同 WHERE 的第二个查询将执行得更快。

【讨论】:

    【解决方案4】:

    避免异常的另一种解决方案:

    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;
    

    【讨论】:

      【解决方案5】:

      合并

      This answer 给出了 Oracle 的示例。


      在不存在的地方插入

      我不确定这是否适用于 Oracle,我相信它适用于 MySQL 和 PostgreSQL 等一般 SQL RDBMS。

      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
      

      请说明拒绝投票的原因:)

      【讨论】:

        【解决方案6】:

        您可以对查询进行参数化,这将花费您 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;
        

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

        【讨论】:

        • 这是一个 SQL Server 答案。问题上的标签清楚地表明这是一个 Oracle 问题。
        猜你喜欢
        • 1970-01-01
        • 2022-06-06
        • 2011-11-20
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 2017-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多