PostgreSQL IF-Anweisung

73

Wie kann ich eine solche Abfrage in Postgres durchführen?

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

Antworten:

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

In Standard-SQL gibt es keine prozeduralen Elemente. Die IFAnweisung ist Teil der Standardprozedursprache PL / pgSQL. Sie müssen mit dem DOBefehl eine Funktion erstellen oder eine Ad-hoc-Anweisung ausführen .

Sie benötigen ein Semikolon ( ;) am Ende jeder Anweisung in plpgsql (mit Ausnahme des FinalesEND ).

Sie müssen END IF;am Ende der IFAnweisung.

Eine Unterauswahl muss in Klammern stehen:

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

Oder:

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

Dies ist jedoch gleichwertig und viel schneller:

    IF EXISTS (SELECT FROM orders) ...

Alternative

Das zusätzliche SELECTwird nicht benötigt. Das geht genauso, schneller:

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

Obwohl dies unwahrscheinlich ist, können gleichzeitige Transaktionen, die in dieselbe Tabelle geschrieben werden, stören. Um absolut sicher zu sein, sperren Sie die Tabelle in derselben Transaktion, bevor Sie wie gezeigt fortfahren.

Erwin Brandstetter
quelle
Funktioniert nicht Ich habe ERROR: Syntaxfehler bei oder in der Nähe von "%" LINE 89:% do%
Luffydude
11
@Luffydude: Und wo würdest du %in meinem Code finden? IOW: Die obigen Anweisungen funktionieren. Sie haben einen nicht verwandten Syntaxfehler eingeführt. Sieht aus wie Sie getippt %do%statt $do$.
Erwin Brandstetter
38

Nur um zu helfen, wenn jemand wie ich über diese Frage stolpert. Wenn Sie in PostgreSQL verwenden möchten, verwenden Sie "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
Mahmood
quelle
7

Aus den Dokumenten

IF boolean-expression THEN
    statements
ELSE
    statements
END IF;

In Ihrem obigen Beispiel sollte der Code also wie folgt aussehen:

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

Sie haben gefehlt: END IF;

Woot4Moo
quelle
3
Ja, ich habe es versucht, aber es funktioniert nicht. FEHLER: Syntaxfehler bei oder in der Nähe von "if"
Vladimir Tsukanov
2
1. Bitte verlinken Sie keine Beta-Dokumente. 2. Ihr Beispiel muss eingeschlossen sein DO, damit es als SQL-Anweisung und nicht in einer PL / pgSQL-Funktion verwendet werden kann.
Milen A. Radev
@ MilenA.Radev Es war die neueste Dokumentation, die auf der Website verfügbar ist. Außerdem baute ich auf dem ersten Beitrag des OP auf, um die korrekte Syntax für die Anweisung anzuzeigen.
Woot4Moo
@VladimirTsukanov weisen Sie den Wert aus der Auswahl einer Variablen zu?
Woot4Moo