it-swarm.com.de

So deklarieren Sie eine Variable in einer PostgreSQL-Abfrage

Wie deklariere ich eine Variable zur Verwendung in einer PostgreSQL 8.3-Abfrage?

In MS SQL Server kann ich dies tun:

DECLARE @myvar INT
SET @myvar = 5

SELECT *
FROM somewhere
WHERE something = @myvar

Wie mache ich dasselbe in PostgreSQL? Laut Dokumentation werden Variablen einfach als "name type;" deklariert, aber dies gibt mir einen Syntaxfehler:

myvar INTEGER;

Könnte mir jemand ein Beispiel für die richtige Syntax geben?

188
EMP

Es gibt keine solche Funktion in PostgreSQL. Sie können dies nur in pl/PgSQL (oder einem anderen pl/*) tun, nicht jedoch in einfachem SQL.

Eine Ausnahme ist WITH () query, die als Variable oder sogar als Tuple von Variablen arbeiten kann. Hiermit können Sie eine Tabelle mit temporären Werten zurückgeben.

WITH master_user AS (
    SELECT
      login,
      registration_date
    FROM users
    WHERE ...
)

SELECT *
FROM users
WHERE master_login = (SELECT login
                      FROM master_user)
      AND (SELECT registration_date
           FROM master_user) > ...;
89
user80168

Ich habe das gleiche Ziel mit einer WITH-Klausel erreicht, sie ist bei weitem nicht so elegant, kann aber dasselbe tun. Obwohl es für dieses Beispiel wirklich übertrieben ist. Das empfehle ich auch nicht besonders.

WITH myconstants (var1, var2) as (
   values (5, 'foo')
)
SELECT *
FROM somewhere, myconstants
WHERE something = var1
   OR something_else = var2;
183
fei0x

Sie können dies auch in PLPGSQL versuchen:

DO $$
DECLARE myvar integer;
BEGIN
    SELECT 5 INTO myvar;

    DROP TABLE IF EXISTS tmp_table;
    CREATE TABLE tmp_table AS
    SELECT * FROM yourtable WHERE   id = myvar;
END $$;

SELECT * FROM tmp_table;

Für das oben Genannte ist Postgres 9.0 oder höher erforderlich.

68

Das hängt von Ihrem Kunden ab.

Wenn Sie jedoch den psql -Client verwenden, können Sie Folgendes verwenden:

my_db=> \set myvar 5
my_db=> SELECT :myvar  + 1 AS my_var_plus_1;
 my_var_plus_1 
---------------
             6

Wenn Sie Textvariablen verwenden, müssen Sie Anführungszeichen setzen.

\set myvar 'sometextvalue'
select * from sometable where name = :'myvar';
45

Dynamische Konfigurationseinstellungen

sie können die dynamischen Konfigurationseinstellungen dafür "missbrauchen":

-- choose some prefix that is unlikely to be used by postgres
set session my.vars.id = '1';

select *
from person 
where id = current_setting('my.vars.id')::int;

Bei den Konfigurationseinstellungen handelt es sich immer um varchar-Werte. Sie müssen sie daher bei der Verwendung in den richtigen Datentyp umwandeln. Dies funktioniert mit jedem SQL-Client, während \set Nur in psql funktioniert.

Für die obigen Angaben ist Postgres 9.2 oder höher erforderlich.

In früheren Versionen musste die Variable vor der Verwendung in postgresql.conf Deklariert werden, was die Verwendbarkeit etwas einschränkte. Eigentlich nicht die Variable komplett, sondern die config "class", die im Wesentlichen das Präfix ist. Sobald das Präfix definiert wurde, kann jede Variable verwendet werden, ohne dass postgresql.conf Geändert wird.

41

Verwenden einer Temp-Tabelle außerhalb von pl/PgSQL

Abgesehen von der vorgeschlagenen Verwendung von pl/pgsql oder einer anderen pl/* -Sprache ist dies die einzige andere Möglichkeit, die mir in den Sinn kommt.

begin;
select 5::int as var into temp table myvar;
select *
  from somewhere s, myvar v
 where s.something = v.var;
commit;
19
joatmon

Ich möchte eine Verbesserung für @ DarioBarrionuevos Antwort vorschlagen, um die Nutzung temporärer Tabellen zu vereinfachen.

DO $$
    DECLARE myvar integer = 5;
BEGIN
    CREATE TEMP TABLE tmp_table ON COMMIT DROP AS
        -- put here your query with variables:
        SELECT * 
        FROM yourtable
        WHERE id = myvar;
END $$;

SELECT * FROM tmp_table;
10
bluish

Diese Lösung basiert auf der von fei0x vorgeschlagenen, hat jedoch den Vorteil, dass die Werteliste der Konstanten in der Abfrage nicht verknüpft werden muss und Konstanten am Anfang der Abfrage einfach aufgelistet werden können. Es funktioniert auch in rekursiven Abfragen.

Grundsätzlich ist jede Konstante eine Einzelwerttabelle , die in einer WITH-Klausel deklariert und dann an einer beliebigen Stelle im restlichen Teil der Abfrage aufgerufen werden kann.

  • Einfaches Beispiel mit zwei Konstanten:
WITH
    constant_1_str AS (VALUES ('Hello World')),
    constant_2_int AS (VALUES (100))
SELECT *
FROM some_table
WHERE table_column = (table constant_1_str)
LIMIT (table constant_2_int)

Alternativ können Sie SELECT * FROM constant_name anstatt TABLE constant_name, das möglicherweise nicht für andere Abfragesprachen als postgresql gültig ist.

5
Jorge Luis

Hier ist ein Beispiel mit PREPARE-Anweisungen . Sie können immer noch nicht ? Verwenden, aber Sie können die $n - Notation verwenden:

PREPARE foo(integer) AS
    SELECT  *
    FROM    somewhere
    WHERE   something = $1;
EXECUTE foo(5);
DEALLOCATE foo;
5
Martin Zinovsky

Es gibt zwar keine anschauliche und eindeutige Möglichkeit, eine einwertige Variable zu deklarieren. Sie können jedoch Folgendes tun

with myVar as (select "any value really")

um dann auf den in dieser Konstruktion gespeicherten Wert zuzugreifen, müssen Sie Folgendes tun

(select * from myVar)

zum Beispiel

with var as (select 123)    
... where id = (select * from var)
4