94

如何在 Postgres 中进行此类查询?

IF (select count(*) from orders) > 0
THEN
  DELETE from orders
ELSE 
  INSERT INTO orders values (1,2,3);
4

4 回答 4

172
DO
$do$
BEGIN
   IF EXISTS (SELECT FROM orders) THEN
      DELETE FROM orders;
   ELSE
      INSERT INTO orders VALUES (1,2,3);
   END IF;
END
$do$

标准 SQL 中没有过程元素。该IF语句是默认过程语言 PL/pgSQL 的一部分。您需要使用命令创建函数或执行临时语句DO

您需要;在 plpgsql 中每条语句的末尾使用分号 ( )(最后的除外END)。

您需要END IF;IF语句的末尾。

子选择必须用括号括起来:

    IF (SELECT count(*) FROM orders) > 0 ...

或者:

    IF (SELECT count(*) > 0 FROM orders) ...

不过,这是等效的,而且速度要快得多:

    IF EXISTS (SELECT FROM orders) ...

选择

SELECT不需要额外的。这同样,更快:

DO
$do$
BEGIN
   DELETE FROM orders;
   IF NOT FOUND THEN
      INSERT INTO orders VALUES (1,2,3);
   END IF;
END
$do$

尽管不太可能,写入同一个表的并发事务可能会干扰。绝对可以肯定的是,在按照演示继续之前,将表写锁定在同一个事务中。

于 2012-07-02T19:28:42.140 回答
52

如果有人像我一样偶然发现这个问题,只是为了帮助,如果你想在 PostgreSQL 中使用 if,你使用“CASE”

select 
    case
        when stage = 1 then 'running'
        when stage = 2 then 'done'
        when stage = 3 then 'stopped'
    else 
        'not running'
    end as run_status from processes
于 2016-05-27T07:01:46.277 回答
9

您还可以使用带有匿名代码块过程块的 PL/pgSQL CASE 的基本结构:

DO $$ BEGIN
    CASE
        WHEN boolean-expression THEN
          statements;
        WHEN boolean-expression THEN
          statements;
        ...
        ELSE
          statements;
    END CASE;
END $$;

参考:

  1. http://www.postgresql.org/docs/current/static/sql-do.html
  2. https://www.postgresql.org/docs/current/static/plpgsql-control-structures.html
于 2016-11-28T21:28:28.900 回答
8

文档

IF boolean-expression THEN
    statements
ELSE
    statements
END IF;

因此,在您上面的示例中,代码应如下所示:

IF select count(*) from orders > 0
THEN
  DELETE from orders
ELSE 
  INSERT INTO orders values (1,2,3);
END IF;

你错过了:END IF;

于 2012-07-02T18:23:09.223 回答