Comment déclarer une variable dans une requête PostgreSQL

Comment déclarer une variable à utiliser dans une requête PostgreSQL 8.3?

dans MS SQL Server je peux faire ceci:

DECLARE @myvar INT
SET @myvar = 5

SELECT *
FROM somewhere
WHERE something = @myvar

Comment puis-je faire la même chose à PostgreSQL? Selon la documentation les variables sont simplement déclarées comme " type de nom;", mais cela me donne une erreur de syntaxe:

myvar INTEGER;

quelqu'un Pourrait-il me donner un exemple de la syntaxe correcte?

137
demandé sur ypercubeᵀᴹ 2009-09-29 10:41:05

8 réponses

il n'y a pas une telle caractéristique dans PostgreSQL. Vous pouvez le faire seulement en pl/ PgSQL (ou autre pl/*), mais pas en SQL simple.

une exception est WITH () requête qui peut fonctionner comme une variable, ou même tuple de variables. Il vous permet de retourner un tableau de valeurs temporaires.

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) > ...;
58
répondu J.Wincewicz 2018-08-09 12:39:18

j'ai atteint le même objectif en utilisant une WITH clause , c'est loin d'être aussi élégant mais peut faire la même chose. Bien que dans cet exemple, c'est vraiment exagéré. Je n'ai pas particulièrement de recommander cette.

WITH myconstants (var1, var2) as (
   values (5, 'foo')
)
SELECT *
FROM somewhere, myconstants
WHERE something = var1
   OR something_else = var2;
142
répondu fei0x 2018-02-21 18:51:29

vous pouvez aussi essayer cela dans PLPGSQL:

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;

ce qui précède nécessite Postgres 9.0 ou plus tard.

52
répondu Dario Barrionuevo 2016-11-15 15:38:31

cela dépend de votre client.

cependant, si vous utilisez le client psql , alors vous pouvez utiliser ce qui suit:

my_db=> \set myvar 5
my_db=> SELECT :myvar  + 1 AS my_var_plus_1;
 my_var_plus_1 
---------------
             6
34
répondu Shahriar Aghajani 2017-11-29 02:44:58

Paramètres De Configuration Dynamiques

vous pouvez "abuser" des paramètres de configuration dynamiques pour cela:

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

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

les paramètres de configuration sont toujours des valeurs varchar, vous devez donc les lancer au bon type de données lorsque vous les utilisez. Cela fonctionne avec N'importe quel client SQL alors que \set ne fonctionne que dans psql

ci-dessus nécessite de Postgresql 9.2 ou version ultérieure.

pour les versions précédentes, la variable a dû être déclarée dans postgresql.conf avant d'être utilisée, de sorte qu'elle a limité quelque peu son utilisabilité. En fait pas complètement la variable, mais la config "class" qui est essentiellement le préfixe. Mais une fois le préfixe défini, n'importe quelle variable pouvait être utilisée sans changer postgresql.conf

33
répondu a_horse_with_no_name 2016-11-11 09:50:48

utilisant une table de température à l'extérieur de pl/PgSQL

en dehors de l'utilisation de pl/pgsql ou d'un autre langage pl/* comme suggéré, c'est la seule autre possibilité à laquelle je pourrais penser.

begin;
select 5::int as var into temp table myvar;
select *
  from somewhere s, myvar v
 where s.something = v.var;
commit;
18
répondu Evan Carroll 2016-11-01 18:16:19

je veux proposer une amélioration à la réponse de @dariobarrionuevo , pour le rendre plus simple en utilisant des tables temporaires.

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;
5
répondu bluish 2017-05-23 12:26:34

voici un exemple d'utilisation de préparer des énoncés . Vous ne pouvez toujours pas utiliser ? , mais vous pouvez utiliser $n notation:

PREPARE foo(integer) AS
    SELECT  *
    FROM    somewhere
    WHERE   something = ;
EXECUTE foo(5);
DEALLOCATE foo;
2
répondu Martin Zinovsky 2018-01-30 16:54:03