Sql 检查行是否存在的最快方法
在将select SOMETHING转换为v_SOMETHING之前,我想知道我的查询是否返回一行 以下是一个很好的方法,但如果行存在,则需要两个选择: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 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