PL/pgSQL检查是否存在行

nny*_*yby 42 sql postgresql exists plpgsql postgresql-9.1

我正在PL/pgSQL中编写一个函数,我正在寻找检查行是否存在的最简单方法.
现在我正在选择一个integer进入a boolean,这不起作用.我对PL/pgSQL还没有足够的经验知道最好的方法.

这是我的功能的一部分:

DECLARE person_exists boolean;
BEGIN

person_exists := FALSE;

SELECT "person_id" INTO person_exists
  FROM "people" p
WHERE p.person_id = my_person_id
LIMIT 1;

IF person_exists THEN
  -- Do something
END IF;

END; $$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

更新 - 我现在正在做这样的事情:

DECLARE person_exists integer;
BEGIN

person_exists := 0;

SELECT count("person_id") INTO person_exists
  FROM "people" p
WHERE p.person_id = my_person_id
LIMIT 1;

IF person_exists < 1 THEN
  -- Do something
END IF;
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 120

更简单,更短,更快: EXISTS.

IF EXISTS (SELECT 1 FROM people p WHERE p.person_id = my_person_id) THEN
  -- do something
END IF;
Run Code Online (Sandbox Code Playgroud)

查询计划程序可以在找到的第一行停止 - 相反count(),它将扫描所有匹配的行,无论如何.与大桌子有所不同.对于唯一列上的条件几乎不重要 - 无论如何只有一行符合条件(并且有一个索引可以快速查找它).

在下面的评论中改进了来自@a_horse_with_no_name的输入.

你甚至可以使用一个空SELECT列表:

IF EXISTS (SELECT FROM people p WHERE p.person_id = my_person_id) THEN ...
Run Code Online (Sandbox Code Playgroud)

由于该SELECT清单与结果无关EXISTS.只有至少一个符合条件的行存在才重要.

  • 具有条件*的`count(*)`*(特别是不在PK列上)将不会**触发顺序扫描. (3认同)
  • @EugenKonkov:我领先:`更简单、更短、更快。` (2认同)

小智 7

使用计数(*)

declare 
   cnt integer;
begin
  SELECT count(*) INTO cnt
  FROM people
  WHERE person_id = my_person_id;

IF cnt > 0 THEN
  -- Do something
END IF;
Run Code Online (Sandbox Code Playgroud)

编辑(针对未阅读该声明的投反对票的人和其他可能正在做类似事情的人)

该解决方案有效,因为列上有一个 where 子句(并且该列的名称表明它是主键 - 因此 where 子句非常有效)

由于该where子句,无需使用 LIMIT 或其他内容来测试由其主键标识的行是否存在。这测试这一点的有效方法。

  • 不要将 COUNT 用于此目的 - 这是性能问题 - 或者您必须使用派生表 SELECT COUNT(*) FROM (SELECT * FROM people LIMIT 1) x (4认同)
  • @a_horse_with_no_name,确切地说 - 它是“微不足道的”SELECT(大约比普通 SELECT 快 10 倍),但它仍然是 SELECT。如果您想查看 plpgsql 代码的真实面貌,请使用 #option dump -- 请参阅文章 http://postgres.cz/wiki/PL/pgSQL_efektivn%C4%9B 中的第一个代码列表(抱歉,文章是捷克语,但示例为英文) - http://translate.google.com/translate?sl=auto&amp;tl=en&amp;u=http%3A%2F%2Fpostgres.cz%2Fwiki%2FPL%2FpgSQL_efektivn%25C4%259B (4认同)
  • @PavelStehule:即使**主键**上有一个“where”条件?我无法想象这怎么会比你的陈述慢得多。两种解决方案的执行计划几乎相同。 (2认同)