Come si usano le variabili in un semplice script PostgreSQL?


Risposte:


132

La risposta completa si trova nella documentazione ufficiale di PostgreSQL .

È possibile utilizzare la nuova funzione di blocco del codice anonimo 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 $$;

Inoltre puoi ottenere l'ultimo ID di inserimento :

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

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

7
(E non dimenticare il ;dopo END $$, in questo modo:. END $$;)
KajMagnus

3
NON FUNZIONA PER ME ERRORE NEAR DO, ho anche alcune funzioni tra l'inizio e la fine con il linguaggio plpgsql.
Ash

51
il codice in questo esempio non funziona. 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
Essendo completamente nuovo in PostgreSQL, questo mi ha lasciato per un po ', ecco alcuni suggerimenti in più: + Assicurati di terminare le tue affermazioni con un punto e virgola! + Poiché non esiste un identificatore di variabile, potresti voler utilizzare _ o qualcosa di simile per evitare nomi di colonna ambigui. + È possibile impostare la variabile su un valore in linea utilizzando in questo modo DECLARE _accountid INT: = 1;
The Coder

1
non lavorare per me. Usando lo scoiattolo. Errore: ERRORE: stringa quotata in dollari non terminata pari o vicino a "$$
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
non lavorare per me. Usando lo scoiattolo. Errore: ERRORE: stringa quotata in dollari non terminata pari o vicino a "$$
Oliver Watkins

1
Mi ci è voluto un po 'per capire che per usare la variabile non devi anteporre a :come con altre variabili. @ achilles-ram-nakirekanti potresti aggiungere un esempio usando questo in una selectdichiarazione per renderlo più chiaro?
exhuma

28

Puoi usare:

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

Questo funzionerà


3
ERRORE: errore di sintassi in corrispondenza o vicino a "\" Cosa mi manca?
scw

14
@scw Disponibile solo dalla psqlconsole. Non sarai in grado di scrivere questo nell'SQL della tua app.
owensmartin

@owensmartin Sarai in grado di usare questo è tutto ciò che viene trasmesso a psql .. o qualsiasi script che psql legge ...
Evan Carroll

4
Questo non risponde affatto alla domanda. In MS SQL puoi definire una var in una query e usarla proprio lì, nello stesso strumento. Non capisco perché la gente continui a proporre questo come risposta, in ogni versione di questa domanda.
pietra

@stone apparentemente perché questa è un'enorme "mancanza" postgresqled è l'alternativa meno peggiore. generalmente sono stato abbastanza soddisfatto postgresql: ma questo è un fallimento sorprendentemente grande
javadba il

10

Ecco un esempio di utilizzo di una variabile in 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

Dai un'occhiata ai documenti plpgsql per maggiori informazioni.


4

Mi sono imbattuto in alcuni altri documenti che usano \setper dichiarare la variabile di scripting, ma il valore sembra essere come un valore costante e sto trovando il modo in cui può agire come una variabile non come una variabile costante.

Ex:

\set Comm 150

select sal, sal+:Comm from emp

Ecco salil valore che è presente nella tabella 'emp' ed commè il valore costante.


2

Ho dovuto fare qualcosa del genere

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

2

Postgresql non ha variabili nude, potresti usare una tabella temporanea. le variabili sono disponibili solo nei blocchi di codice o come funzionalità dell'interfaccia utente.

Se hai bisogno di una variabile nuda, potresti usare una tabella temporanea:

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

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

Come vantaggio collaterale, questo approccio è indipendente dal database, rendendo i test più portabili attraverso il backend.
vescovo

2

Basandosi sulla risposta di @ nad2000 e sulla risposta di @ Pavel qui , è qui che sono finito per i miei script di migrazione Flyway. Gestione di scenari in cui lo schema del database è stato modificato manualmente.

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

Per utilizzare le variabili, ad esempio, 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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.