Armazenar o resultado da consulta em uma variável usando no PL / pgSQL

130

Como atribuir o resultado de uma consulta a uma variável no PL / pgSQL, a linguagem processual do PostgreSQL?

Eu tenho uma função:

CREATE OR REPLACE FUNCTION test(x numeric)
RETURNS character varying AS
$BODY$
DECLARE
name   character varying(255);
begin
 name ='SELECT name FROM test_table where id='||x;

 if(name='test')then
  --do somthing
 else
  --do the else part
 end if;
end;
return -- return my process result here
$BODY$
LANGUAGE plpgsql VOLATILE

Na função acima, eu preciso armazenar o resultado desta consulta:

'SELECT name FROM test_table where id='||x;

para a variável name .

Como processar isso?

Sathish
fonte

Respostas:

198

Eu acho que você está procurando SELECT INTO:

select test_table.name into name from test_table where id = x;

Isso irá extrair namede test_tableonde idestá o argumento da sua função e deixá-lo na namevariável Não deixe de fora o prefixo do nome da tabela test_table.nameou você receberá reclamações sobre uma referência ambígua.

mu é muito curto
fonte
2
E se eu precisar de várias variáveis. Como selecione test_table.name, test_table.id, test_table.ssn?
Dao Lam
2
@DaoLam: Na documentação que eu gostei de: "O resultado de um comando SQL produzindo uma única linha (possivelmente de várias colunas) pode ser atribuído a uma variável de registro, variável de tipo de linha ou lista de variáveis ​​escalares."
mu é muito curto
@muistooshort, então você está dizendo que eu posso fazer o mesmo e usar name.id, name.ssn para recuperar? Eu tentei com IF existe, mas não funcionou: IF EXISTS (SELECT * em nome de test_table ...))
Dao Lam
@DaoLam Por que você está combinando INTO com IF EXISTS? Talvez você deva fazer uma nova pergunta para poder explicar o que está tentando fazer.
mu é muito curto
3
Não há exemplo na documentação (ou eu perdi), mas como @muistooshort observou, você pode selecionar em várias variáveis com seleção única:SELECT test_table.column1, test_table.column2 INTO variable1, variable2 FROM test_table WHERE id = x;
Grengas
78

Contanto que você esteja atribuindo uma única variável, você também pode usar a atribuição simples em uma função plpgsql:

name := (SELECT t.name from test_table t where t.id = x);

Ou use SELECT INTOcomo o @mu já fornecido .

Isso também funciona:

name := t.name from test_table t where t.id = x;

Mas é melhor usar um dos dois primeiros, métodos mais claros, como o @Pavel comentou.

Também reduzi a sintaxe com um alias de tabela.
Update: eu removi meu exemplo de código e sugerir a utilização IF EXISTS()em vez como fornecido pelo @Pavel .

Erwin Brandstetter
fonte
1
Este não é boa idéia - este recurso não está documentado e é feio
Pavel Stehule
2
PL / pgSQL permite misturar SQL e PL - e às vezes você pode criar criaturas realmente estranhas, mas é melhor misturar PL e SQL de maneira limpa - em instruções isoladas.
Pavel Stehule
@PavelStehule: Concordo, seu formulário é preferível.
Erwin Brandstetter
Na verdade, eu prefiro sua sintaxe, mas o problema é que, quando você lida com erros, sua instrução não envia FOUND para true no oposto da instrução select into, checkout ( postgresql.org/docs/9.1/plpgsql-statements.html )
SENHAJI RHAZI Hamza
18

O padrão usual é EXISTS(subselect):

BEGIN
  IF EXISTS(SELECT name
              FROM test_table t
             WHERE t.id = x
               AND t.name = 'test')
  THEN
     ---
  ELSE
     ---
  END IF;

Esse padrão é usado em PL / SQL, PL / pgSQL, SQL / PSM, ...

Pavel Stehule
fonte
2

Criar tabela de aprendizado:

CREATE TABLE "public"."learning" (
    "api_id" int4 DEFAULT nextval('share_api_api_id_seq'::regclass) NOT NULL,
    "title" varchar(255) COLLATE "default"
);

Inserir tabela de aprendizado de dados:

INSERT INTO "public"."learning" VALUES ('1', 'Google AI-01');
INSERT INTO "public"."learning" VALUES ('2', 'Google AI-02');
INSERT INTO "public"."learning" VALUES ('3', 'Google AI-01');

Etapa: 01

CREATE OR REPLACE FUNCTION get_all (pattern VARCHAR) RETURNS TABLE (
        learn_id INT,
        learn_title VARCHAR
) AS $$
BEGIN
    RETURN QUERY SELECT
        api_id,
        title
    FROM
        learning
    WHERE
        title = pattern ;
END ; $$ LANGUAGE 'plpgsql';

Etapa: 02

SELECT * FROM get_all('Google AI-01');

Etapa: 03

DROP FUNCTION get_all();

Demo: insira a descrição da imagem aqui

Ram Pukar
fonte
-2

Você pode usar o exemplo a seguir para armazenar um resultado da consulta em uma variável usando PL / pgSQL:

 select * into demo from maintenanceactivitytrack ; 
    raise notice'p_maintenanceid:%',demo;
rinku Choudhary
fonte