Jak używać zmiennych w prostym skrypcie PostgreSQL?


Odpowiedzi:


132

Pełna odpowiedź znajduje się w oficjalnej dokumentacji PostgreSQL .

Możesz użyć nowej funkcji blokowania anonimowego kodu 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 $$;

Możesz również uzyskać ostatni identyfikator wkładki :

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

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

7
(I nie zapomnij ;po END $$, tak: END $$;.)
KajMagnus

3
NIE DZIAŁA DLA MNIE BŁĄD BLISKO ROBIĆ, mam też kilka funkcji między początkiem a końcem z językiem plpgsql.
Ash

51
kod w tym przykładzie nie działa. 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
Zupełnie nowy w PostgreSQL na chwilę mnie to zrzuciło. Oto kilka dodatkowych wskazówek: + Upewnij się, że kończysz swoje instrukcje średnikiem! + Ponieważ nie ma identyfikatora zmiennej, możesz chcieć użyć znaku _ lub czegoś podobnego, aby uniknąć niejednoznacznych nazw kolumn. + Możesz ustawić zmienną na wartość w linii, używając w ten sposób DECLARE _accountid INT: = 1;
The Coder

1
nie pracuj dla mnie. Za pomocą wiewiórki. Błąd: BŁĄD: niezakończony ciąg znaków w dolarach równy lub zbliżony do „$$
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
nie pracuj dla mnie. Za pomocą wiewiórki. Błąd: BŁĄD: niezakończony ciąg znaków w dolarach równy lub zbliżony do „$$
Oliver Watkins

1
Zajęło mi trochę czasu, zanim zrozumiałem, że aby użyć zmiennej, nie możesz poprzedzać jej znakiem a, :jak w przypadku innych zmiennych. @ achilles-ram-nakirekanti, możesz dodać przykład używając tego w selectoświadczeniu, aby było jaśniejsze?
exhuma

28

Możesz użyć:

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

To wystarczy


3
BŁĄD: błąd składni na poziomie „\” lub w pobliżu Czego brakuje?
Śr

14
@scw To jest dostępne tylko z psqlkonsoli. Nie będziesz w stanie zapisać tego w kodzie SQL swojej aplikacji.
owensmartin

@owensmartin Będziesz mógł użyć tego wszystkiego, co jest przesłane do psql .. lub dowolnego skryptu, który czyta psql ...
Evan Carroll

4
To wcale nie odpowiada na pytanie. W MS SQL możesz zdefiniować zmienną w zapytaniu i użyć jej w tym samym narzędziu. Nie rozumiem, dlaczego ludzie wciąż proponują to jako odpowiedź w każdej wersji tego pytania.
kamień

@stone najwyraźniej dlatego, że jest to ogromny „brak” postgresqli jest to najmniej najgorsza alternatywa. ogólnie postgresql
jestem

10

Oto przykład użycia zmiennej w 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

Zapoznaj się z dokumentacją plpgsql, aby uzyskać więcej informacji.


4

Natknąłem się na kilka innych dokumentów, których używają \setdo deklarowania zmiennej skryptowej, ale wartość wydaje się być wartością stałą i znajduję sposób, który może działać jak zmienna, a nie zmienna stała.

Dawny:

\set Comm 150

select sal, sal+:Comm from emp

Oto salwartość, która jest obecna w tabeli „emp” i commjest wartością stałą.


2

Musiałem zrobić coś takiego

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

2

Postgresql nie ma pustych zmiennych, możesz użyć tabeli tymczasowej. zmienne są dostępne tylko w blokach kodu lub jako funkcja interfejsu użytkownika.

Jeśli potrzebujesz czystej zmiennej, możesz użyć tabeli tymczasowej:

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

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

Dodatkową korzyścią jest to, że podejście to jest niezależne od bazy danych, dzięki czemu testy są bardziej przenośne w ramach zaplecza.
biskup

2

Opierając się na odpowiedzi @ nad2000 i odpowiedzi @ Pavel tutaj , w tym miejscu znalazłem moje skrypty migracji Flyway. Obsługa scenariuszy, w których schemat bazy danych został ręcznie zmodyfikowany.

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

Do wykorzystania zmiennych na przykład w tablicy alter:

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;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.