sql >> Database teknologi >  >> RDS >> PostgreSQL

Brug variabel indstillet af psql-metakommando inde i DO-blokken

Svar

DO forventer en streng literal med plpgsql-kode. Symboler erstattes ikke inde i strenge i psql.
Du kan sammenkæde hele strengen i en psql-variabel og derefter udføre det.

  • Hvordan sammenkædes psql-variabler?

Temmelig multi-line format er ikke muligt, fordi (pr. dokumentation):

Men under alle omstændigheder kan argumenterne for en metakommando ikke fortsætte ud over slutningen af ​​linjen.

Simpelt eksempel:

test=# \set value foo
test=# \set do 'BEGIN\n   RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
test=# DO :'do';
NOTICE:  v: foo

Erstat linjeskift med \n (eller fjern dem, hvis du er ligeglad med smukt format). Baseret på denne tilpassede kode:

DO
'
DECLARE
   _val  text;
   _vals text[] := string_to_array(>>values<<, '','');
BEGIN
   FOREACH _val IN ARRAY _vals
   LOOP
     RAISE NOTICE ''v: %'', _val;
   END LOOP;
END
'

Det ser sådan ud:

test=# \set do 'DECLARE\n   _val  text;\n   _vals text[] := string_to_array(' :'values' ', '','');\nBEGIN\n   FOREACH _val IN ARRAY _vals\n   LOOP\n     RAISE NOTICE ''v: %'', _val;\n   END LOOP;\nEND'
test=# DO :'do';
NOTICE:  v: foo
NOTICE:  v: bar
NOTICE:  v: baz
DO

Jeg tilføjede fed fremhævelse af variablen for at gøre den nemmere at få øje på.

Relateret svar fra @Pavel (ab) ved hjælp af en serversessionsvariabel:

  • Hviserer til sessionsvariabler (\set var='value') fra PL/PGSQL

Alternative løsninger

Udarbejdet erklæring

Din nuværende løsning ser ikke så dårlig ud. Jeg vil forenkle:

PREPARE get_values AS SELECT * FROM regexp_split_to_table(:'values', ',');

DO
$do$
DECLARE
   _val text;
BEGIN
   FOR _val IN EXECUTE
      'EXECUTE get_values'
   LOOP
      RAISE NOTICE 'v: %', _val;
   END LOOP;
END
$do$;

Midlertidig tabel

Lignende løsning med en midlertidig tabel:

CREATE TEMP TABLE tmp AS SELECT * FROM regexp_split_to_table(:'values', ',') v;

DO
$do$
DECLARE
   _val text;
BEGIN
   FOR _val IN
      TABLE tmp
   LOOP
      RAISE NOTICE 'v: %', _val;
   END LOOP;
END
$do$;


  1. Kalder lagret procedure med Out-parameter ved hjælp af PDO

  2. NLS_LOWER() Funktion i Oracle

  3. Implementering af en tilpasset sortering

  4. Python MySQL-stik - ulæst resultat fundet ved brug af fetchone