web-dev-qa-db-ja.com

PostgreSQL IFステートメント

Postgresでこのようなクエリを実行するにはどうすればよいですか?

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

試してください:

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 statement は、デフォルトの手続き型言語PL/pgSQLの一部です。 DO コマンドを使用して、関数を作成するか、アドホックステートメントを実行する必要があります。

  • Plpgsqlの各ステートメントの最後に;が必要です( 最終的なEND を除く)。

  • IFステートメントの最後にEND 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$

可能性は低いですが、同じテーブルへの書き込みを試みる同時トランザクションが干渉する可能性があります。確かに、 write-lock は、示されているように進む前に同じトランザクション内のテーブルです。

105

私のようなこの質問に誰かがつまずいた場合に役立つように、PostgreSQLで使用したい場合は、「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
24
Mahmood

docs から

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;

8
Woot4Moo

PL/pgSQL CASEの基本構造を anonymous code block procedureブロックで使用することもできます:

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
5
user