Comment utilisez-vous des variables dans un simple script PostgreSQL?


Réponses:


131

La réponse complète se trouve dans la documentation officielle de PostgreSQL .

Vous pouvez utiliser la nouvelle fonctionnalité de blocage de code anonyme PG9.0 ( http://www.postgresql.org/docs/9.1/static/sql-do.html )

DO $$
DECLARE v_List TEXT;
BEGIN
  v_List := 'foobar' ;
  SELECT *
  FROM   dbo.PubLists
  WHERE  Name = v_List;
  -- ...
END $$;

Vous pouvez également obtenir le dernier identifiant d' insertion :

DO $$
DECLARE lastid bigint;
BEGIN
  INSERT INTO test (name) VALUES ('Test Name') 
  RETURNING id INTO lastid;

  SELECT * FROM test WHERE id = lastid;
END $$;

7
(Et n'oubliez pas l' ;après END $$, comme ceci END $$;
:.

3
NE FONCTIONNE PAS POUR MOI ERREUR NEAR DO, j'ai aussi quelques fonctions entre le début et la fin avec le langage plpgsql.
Ash

49
le code de cet exemple ne fonctionne pas. ERROR: query has no destination for result data HINT: If you want to discard the results of a SELECT, use PERFORM instead. CONTEXT: PL/pgSQL function inline_code_block line 7 at SQL statement
Jasen

1
Étant complètement nouveau dans PostgreSQL, cela m'a jeté pendant un certain temps, voici quelques conseils supplémentaires: + Assurez-vous de terminer vos déclarations par un point-virgule! + Comme il n'y a pas d'identificateur de variable, vous pouvez utiliser un _ ou quelque chose de similaire pour éviter les noms de colonne ambigus. + Vous pouvez définir la variable sur une valeur en ligne en utilisant comme ceci DECLARE _accountid INT: = 1;
The Coder

1
ne fonctionne pas pour moi. Utilisation de l'écureuil. Erreur: ERREUR: chaîne entre guillemets en dollars non terminée à ou près de "$$
Oliver Watkins

39
DO $$
DECLARE  
   a integer := 10;  
   b integer := 20;  
   c integer;  
BEGIN  
   c := a + b;
    RAISE NOTICE'Value of c: %', c;
END $$;

3
ne fonctionne pas pour moi. Utilisation de l'écureuil. Erreur: ERREUR: chaîne entre guillemets en dollars non terminée à ou près de "$$
Oliver Watkins

Il m'a fallu un certain temps pour comprendre que pour utiliser la variable, vous ne devez pas la préfixer avec un :comme avec d'autres variables. @ achilles-ram-nakirekanti vous pourriez ajouter un exemple en utilisant ceci dans une selectdéclaration pour rendre cela plus clair?
exhuma

28

Vous pouvez utiliser:

\set list '''foobar'''
SELECT * FROM dbo.PubLists WHERE name = :list;

Ça va faire


3
ERREUR: erreur de syntaxe à ou près de "\" Que me manque-t-il?
scw

14
@scw Ceci n'est disponible qu'à partir de la psqlconsole. Vous ne pourrez pas écrire cela dans le SQL de votre application.
owensmartin

@owensmartin Vous pourrez utiliser tout ce qui est acheminé vers psql .. ou tout autre script que psql lit ...
Evan Carroll

4
Cela ne répond pas du tout à la question. Dans MS SQL, vous pouvez définir une variable dans une requête et l'utiliser directement, dans le même outil. Je ne comprends pas pourquoi les gens continuent de proposer cela comme réponse, dans chaque version de cette question.
pierre

@stone apparemment parce que c'est un énorme "raté" postgresqlet c'est l'alternative la moins mauvaise. en général, je suis assez satisfait postgresql: mais c'est un échec étonnamment gros
javadba

10

Voici un exemple d'utilisation d'une variable dans plpgsql:

create table test (id int);
insert into test values (1);
insert into test values (2);
insert into test values (3);

create function test_fn() returns int as $$
    declare val int := 2;
    begin
        return (SELECT id FROM test WHERE id = val);
    end;
$$ LANGUAGE plpgsql;

SELECT * FROM test_fn();
 test_fn 
---------
       2

Jetez un œil à la documentation plpgsql pour plus d'informations.


4

Je suis tombé sur d'autres documents qu'ils utilisent \setpour déclarer une variable de script, mais la valeur semble être une valeur constante et je trouve un moyen qui peut agir comme une variable et non comme une variable constante.

Ex:

\set Comm 150

select sal, sal+:Comm from emp

Voici salla valeur qui est présente dans la table 'emp' et commest la valeur constante.


2

Je devais faire quelque chose comme ça

CREATE OR REPLACE FUNCTION MYFUNC()
RETURNS VOID AS $$
DO
$do$
BEGIN
DECLARE
 myvar int;
 ...
END
$do$
$$ LANGUAGE SQL;

2

Postgresql n'a pas de variables nues, vous pouvez utiliser une table temporaire. les variables ne sont disponibles que dans des blocs de code ou en tant que fonctionnalité d'interface utilisateur.

Si vous avez besoin d'une variable nue, vous pouvez utiliser une table temporaire:

CREATE TEMP TABLE list AS VALUES ('foobar');

SELECT dbo.PubLists.*
FROM   dbo.PubLists,list
WHERE  Name = list.column1;

En outre, cette approche est indépendante de la base de données, ce qui rend vos tests plus portables sur le backend.
évêque

2

Sur la base de la réponse de @ nad2000 et de la réponse de @ Pavel ici , c'est là que je me suis retrouvé pour mes scripts de migration Flyway. Gestion des scénarios où le schéma de base de données a été modifié manuellement.

DO $$
BEGIN
    IF NOT EXISTS(
        SELECT TRUE FROM pg_attribute 
        WHERE attrelid = (
            SELECT c.oid
            FROM pg_class c
            JOIN pg_namespace n ON n.oid = c.relnamespace
            WHERE 
                n.nspname = CURRENT_SCHEMA() 
                AND c.relname = 'device_ip_lookups'
            )
        AND attname = 'active_date'
        AND NOT attisdropped
        AND attnum > 0
        )
    THEN
        RAISE NOTICE 'ADDING COLUMN';        
        ALTER TABLE device_ip_lookups
            ADD COLUMN active_date TIMESTAMP;
    ELSE
        RAISE NOTICE 'SKIPPING, COLUMN ALREADY EXISTS';
    END IF;
END $$;


1

Pour utiliser des variables dans, par exemple, alter table:

DO $$ 
DECLARE name_pk VARCHAR(200);
BEGIN
select constraint_name
from information_schema.table_constraints
where table_schema = 'schema_name'
      and table_name = 'table_name'
      and constraint_type = 'PRIMARY KEY' INTO name_pk;
IF (name_pk := '') THEN
EXECUTE 'ALTER TABLE schema_name.table_name DROP CONSTRAINT ' || name_pk;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.