Stocker le résultat de la requête dans une variable en utilisant dans PL / pgSQL

130

Comment affecter le résultat d'une requête à une variable dans PL / pgSQL, le langage procédural de PostgreSQL?

J'ai une fonction:

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

Dans la fonction ci-dessus, j'ai besoin de stocker le résultat de cette requête:

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

à la variable name .

Comment traiter cela?

Sathish
la source

Réponses:

198

Je pense que vous recherchez SELECT INTO:

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

Cela tirera le named' test_tableidest l'argument de votre fonction et le laissera dans la namevariable. Ne laissez pas le préfixe du nom de la table sur test_table.nameou vous recevrez des plaintes concernant une référence ambiguë.

mu est trop court
la source
2
Et si j'ai besoin de plusieurs variables. Comme select test_table.name, test_table.id, test_table.ssn?
Dao Lam
2
@DaoLam: D'après la documentation, j'ai aimé: "Le résultat d'une commande SQL donnant une seule ligne (éventuellement de plusieurs colonnes) peut être assigné à une variable d'enregistrement, une variable de type ligne ou une liste de variables scalaires."
mu est trop court
@muistooshort alors vous dites que je peux faire de même et que je peux utiliser name.id, name.ssn pour récupérer? Je l'ai essayé avec IF EXISTS mais n'a pas fonctionné: IF EXISTS (sélectionnez * dans le nom de test_table ...))
Dao Lam
@DaoLam Pourquoi combinez-vous INTO avec IF EXISTS? Vous devriez peut-être poser une nouvelle question pour pouvoir expliquer ce que vous essayez de faire.
mu est trop court
3
Il n'y a pas d'exemple dans la documentation (ou je l'ai manqué), mais comme @muistooshort l'a noté, vous pouvez sélectionner plusieurs variables avec une seule sélection:SELECT test_table.column1, test_table.column2 INTO variable1, variable2 FROM test_table WHERE id = x;
Grengas
78

Tant que vous affectez une seule variable, vous pouvez également utiliser une affectation simple dans une fonction plpgsql:

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

Ou utilisez SELECT INTOcomme @mu déjà fourni .

Cela fonctionne aussi:

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

Mais mieux vaut utiliser l'une des deux premières méthodes plus claires, comme l'a commenté @Pavel.

J'ai raccourci la syntaxe avec un alias de table en plus.
Mise à jour: J'ai supprimé mon exemple de code et suggère de l'utiliser à la IF EXISTS()place comme fourni par @Pavel .

Erwin Brandstetter
la source
1
Ce n'est pas une bonne idée - cette fonctionnalité n'est pas documentée et elle est moche
Pavel Stehule
2
PL / pgSQL permet de mélanger SQL et PL - et parfois vous pouvez créer des créatures vraiment étranges, mais il vaut mieux mélanger PL et SQL proprement - dans des instructions isolées.
Pavel Stehule
@PavelStehule: Je suis d'accord, votre forme est préférable.
Erwin Brandstetter
En fait, je préfère votre syntaxe, mais le problème est que lorsque vous voulez gérer les erreurs, votre déclaration n'envoie pas FOUND à true à l'opposé de l'instruction select into, checkout ( postgresql.org/docs/9.1/plpgsql-statements.html )
SENHAJI RHAZI Hamza
18

Le modèle habituel est EXISTS(subselect):

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

Ce modèle est utilisé en PL / SQL, PL / pgSQL, SQL / PSM, ...

Pavel Stehule
la source
2

Créer une table d'apprentissage:

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

Insérer un tableau d'apprentissage des données:

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');

Étape: 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';

Étape: 02

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

Étape: 03

DROP FUNCTION get_all();

Démo: entrez la description de l'image ici

Ram Pukar
la source
-2

Vous pouvez utiliser l'exemple suivant pour stocker un résultat de requête dans une variable à l'aide de PL / pgSQL:

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