Como você usa variáveis ​​em um script PostgreSQL simples?

Respostas:

131

A resposta completa está localizada na documentação oficial do PostgreSQL .

Você pode usar o novo recurso de bloqueio de código anônimo 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 $$;

Além disso, você pode obter o último id de inserção :

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

  SELECT * FROM test WHERE id = lastid;
END $$;
nad2000
fonte
7
(E não se esqueça do ;depois END $$, assim:. END $$;)
KajMagnus
3
NÃO FUNCIONA PARA MIM ERRO PERTO DO, Eu também tenho algumas funções entre o início e o fim com a linguagem plpgsql.
Ash,
49
o código neste exemplo não funciona. 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
Por ser completamente novo no PostgreSQL, isso me confundiu por um tempo, aqui estão mais algumas dicas: + Certifique-se de terminar suas instruções com um ponto e vírgula! + Como não há identificador de variável, você pode querer usar um _ ou algo semelhante para evitar nomes de coluna ambíguos. + Você pode definir a variável para um valor em linha usando, assim, DECLARE _accountid INT: = 1;
The Coder
1
não trabalhe para mim. Usando o esquilo. Erro: ERRO: string não terminada entre aspas em dólares em ou perto 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 $$;
Achilles Ram Nakirekanti
fonte
3
não trabalhe para mim. Usando o esquilo. Erro: ERRO: string não terminada entre aspas em dólares em ou perto de "$$
Oliver Watkins
Levei um tempo para descobrir que, para usar a variável, você não deve prefixá-la com um :como com outras variáveis. @ achilles-ram-nakirekanti você poderia adicionar um exemplo usando isso em uma selectdeclaração para tornar isso mais claro?
exhuma
28

Você pode usar:

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

Que vai fazer

Karim de Alba
fonte
3
ERROR: erro de sintaxe em ou próximo a "\" O que estou perdendo?
scw
14
@scw Isso só está disponível no psqlconsole. Você não poderá escrever isso no SQL do seu aplicativo.
owensmart em
@owensmartin Você poderá usar isso é qualquer coisa canalizada para o psql .. ou qualquer script que o psql leia ...
Evan Carroll
4
Isso não responde à pergunta de forma alguma. No MS SQL você pode definir uma var em uma consulta e usá-la ali mesmo, na mesma ferramenta. Não entendo por que as pessoas continuam propondo isso como uma resposta, em todas as versões dessa pergunta.
pedra de
@stone aparentemente porque esta é uma grande "falta" postgresqle é a alternativa menos-pior. geralmente postgresql
fico
10

Aqui está um exemplo de uso de uma variável em 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

Dê uma olhada na documentação do plpgsql para mais informações.

pensar demais
fonte
4

Eu encontrei alguns outros documentos que eles usam \setpara declarar a variável de script, mas o valor parece ser como um valor constante e estou descobrindo uma maneira que pode atuar como uma variável, não uma variável constante.

Ex:

\set Comm 150

select sal, sal+:Comm from emp

Aqui salestá o valor que está presente na tabela 'emp' e commé o valor constante.

Vinodraj
fonte
2

Eu tive que fazer algo assim

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

Postgresql não tem variáveis ​​nuas, você pode usar uma tabela temporária. as variáveis ​​estão disponíveis apenas em blocos de código ou como um recurso de interface do usuário.

Se você precisar de uma variável simples, poderá usar uma tabela temporária:

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

SELECT dbo.PubLists.*
FROM   dbo.PubLists,list
WHERE  Name = list.column1;
Jasen
fonte
Como benefício colateral, essa abordagem é independente do banco de dados, tornando seus testes mais portáteis no back-end.
bispo
2

Com base na resposta de @ nad2000 e na resposta de @Pavel aqui , foi aqui que acabei meus scripts de migração do Flyway. Tratamento de cenários em que o esquema do banco de dados foi modificado 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 $$;
Shane
fonte
1

Para o cliente CLI oficial "psql", consulte aqui . E o "pgAdmin3" 1.10 (ainda em beta) tem o " pgScript ".

Milen A. Radev
fonte
1

Para usar variáveis ​​em, por exemplo, 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;
David Leon
fonte