Comment déclarer une variable à utiliser dans une requête PostgreSQL 8.3?
Dans MS SQL Server, je peux le faire:
DECLARE @myvar INT
SET @myvar = 5
SELECT *
FROM somewhere
WHERE something = @myvar
Comment faire la même chose dans 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?
Il n’existe pas de telle fonctionnalité dans PostgreSQL. Vous pouvez le faire uniquement dans pl/PgSQL (ou autre pl/*), mais pas en langage SQL simple.
Une exception est la requête WITH ()
qui peut fonctionner en tant que variable, ou même Tuple
de variables. Il vous permet de renvoyer une table 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) > ...;
J'ai atteint le même objectif en utilisant une clause _ (WITH
) , c'est loin d'être aussi élégant, mais je peux faire la même chose. Bien que pour cet exemple, c'est vraiment exagéré. Je ne recommande pas particulièrement cela.
WITH myconstants (var1, var2) as (
values (5, 'foo')
)
SELECT *
FROM somewhere, myconstants
WHERE something = var1
OR something_else = var2;
Vous pouvez également essayer ceci 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;
Ceci nécessite Postgres 9.0 ou une version ultérieure.
Cela dépend de votre client.
Toutefois, si vous utilisez le client psql, vous pouvez utiliser les éléments suivants:
my_db=> \set myvar 5
my_db=> SELECT :myvar + 1 AS my_var_plus_1;
my_var_plus_1
---------------
6
Si vous utilisez des variables de texte, vous devez citer.
\set myvar 'sometextvalue'
select * from sometable where name = :'myvar';
vous pouvez "abuser" des paramètres de configuration dynamiques pour cela:
-- 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;
Les paramètres de configuration sont toujours des valeurs varchar. Vous devez donc les attribuer au type de données approprié lors de leur utilisation. Cela fonctionne avec n'importe quel client SQL alors que \set
ne fonctionne que dans psql
Ceci nécessite Postgres 9.2 ou une version ultérieure.
Pour les versions précédentes, la variable devait être déclarée dans postgresql.conf
avant d'être utilisée, ce qui limitait quelque peu sa convivialité. En fait, pas complètement la variable, mais la "classe" de configuration qui est essentiellement le préfixe. Mais une fois le préfixe défini, toute variable pouvait être utilisée sans modifier postgresql.conf
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 pouvais penser.
begin;
select 5::int as var into temp table myvar;
select *
from somewhere s, myvar v
where s.something = v.var;
commit;
Je souhaite proposer une amélioration à réponse de @ DarioBarrionuevo , afin de simplifier l'utilisation 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;
Cette solution est basée sur celle proposée par fei0x mais présente les avantages qu’il n’est pas nécessaire de joindre la liste de valeurs des constantes dans la requête et que les constantes peuvent facilement être listées au début de la requête. Cela fonctionne aussi dans les requêtes récursives.
Fondamentalement, chaque constante est une table à valeur unique déclarée dans une clause WITH qui peut ensuite être appelée n'importe où dans la partie restante de la requête.
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)
Vous pouvez également utiliser SELECT * FROM constant_name
au lieu de TABLE constant_name
, qui peut ne pas être valide pour d'autres langages de requête différents de postgresql.
Voici un exemple d'utilisation de instructions PREPARE . Vous ne pouvez toujours pas utiliser ?
, mais vous pouvez utiliser la notation $n
:
PREPARE foo(integer) AS
SELECT *
FROM somewhere
WHERE something = $1;
EXECUTE foo(5);
DEALLOCATE foo;
Certes, il n’existe pas de moyen clair et sans équivoque de déclarer une variable à valeur unique, vous pouvez faire ce qui suit:
with myVar as (select "any value really")
puis, pour avoir accès à la valeur stockée dans cette construction, vous devez
(select * from myVar)
par exemple
with var as (select 123)
... where id = (select * from var)