关于sql:PostgreSQL IF语句

PostgreSQL IF statement

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

1
2
3
4
5
IF (SELECT COUNT(*) FROM orders) > 0
THEN
  DELETE FROM orders
ELSE
  INSERT INTO orders VALUES (1,2,3);

尝试:

1
2
3
4
5
6
7
8
9
10
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除外)。

  • IF语句的末尾需要END IF;

  • 子选择需要用括号括起来:

    1
    IF (SELECT COUNT(*) FROM orders) > 0 ...

    要么:

    1
    IF (SELECT COUNT(*) > 0 FROM orders) ...

    这是等效的,但速度更快:

    1
    IF EXISTS (SELECT FROM orders) ...

另类

实际上,您实际上根本不需要额外的SELECT。这样做相同,但速度更快:

1
2
3
4
5
6
7
8
9
DO
$do$
BEGIN
DELETE FROM orders;
IF NOT FOUND THEN
   INSERT INTO orders VALUES (1,2,3);
END IF;
END
$do$

尽管不太可能,但尝试写入同一表的并发事务可能会造成干扰。绝对可以肯定,在进行演示之前,将表写锁定在同一事务中。


只是为了帮助任何人像我一样偶然遇到这个问题,
如果要在PostgreSQL中使用if,请使用" CASE"

1
2
3
4
5
6
7
8
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


来自文档

1
2
3
4
5
IF boolean-expression THEN
    statements
ELSE
    statements
END IF;

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

1
2
3
4
5
6
IF SELECT COUNT(*) FROM orders > 0
THEN
  DELETE FROM orders
ELSE
  INSERT INTO orders VALUES (1,2,3);
END IF;

您不见了:END IF;


您还可以将PL / pgSQL CASE的基本结构与匿名代码块过程块一起使用:

1
2
3
4
5
6
7
8
9
10
11
DO $$ BEGIN
    CASE
        WHEN boolean-expression THEN
          statements;
        WHEN boolean-expression THEN
          statements;
        ...
        ELSE
          statements;
    END CASE;
END $$;

参考文献:

  • http://www.postgresql.org/docs/current/static/sql-do.html
  • https://www.postgresql.org/docs/current/static/plpgsql-control-structures.html