PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 15/02/2017 13:31:44

execute into

Bonjour,

Je veux tester la présence d'un record dans une table avec

        stmt := 'select audit_idid from public.' || quote_ident(r.table_name) || ' where audit_id = ' || r.audit_id || ';';
        execute stmt into this_audit_id;

si le record est là, tout va bien. Mais si le record n'est pas là

                info := 'this_audit_id = ' || this_audit_id;
                insert into sync_log values (schema_name, info);

ne m'écrira même pas 'this_audit_id' !?  J'ai essayé plusieurs trucs avec coalesce mais je pédale dans la choucroute...


Par ailleurs, puis-je être² assuré que

        select "ContactID" into this_pk from public."tblContacts" where audit_id = r.audit_id;

        if not found then

fonctionnera dans tous les cas.

Hors ligne

#2 15/02/2017 14:49:00

Re : execute into

Cher collègue,

Tu fais :

execute stmt into this_audit_id;
        get diagnostics rcount = ROW_COUNT;
        if rcount = 0 then

et l'affaire est dans le sac.

Hors ligne

#3 15/02/2017 20:16:29

gleu
Administrateur

Re : execute into

Il n'écrit pas "this_audit_id = ' parce que this_audit_id vaut NULL et que concaténer une chaîne à une valeur inconnue (NULL) produit une valeur inconnue, donc NULL. Pour que cela fonctionne, il faudrait soit utiliser la fonction coalesce, soit tester si this_audit_id vaut NULL, soit faire le test de la valeur de la variable FOUND.

Hors ligne

#4 16/02/2017 13:43:53

Re : execute into

Merci pour ces éclaircissements.

Quelle est la méthode la plus sûre pour tester la présence d'un record dans une table ?

Est-ce que

        select "ContactID" into this_pk from public."tblContacts" where audit_id = r.audit_id;

        if not found then
             ...

marchera dans tous les cas ?

Par ailleurs, la migration se passe bien. On garde MS Access comme front-end et les performances sont très bonnes. Merci pg !

Hors ligne

#5 17/02/2017 16:57:38

dverite
Membre

Re : execute into

Autant faire directement

 IF not exists (select 1 from public."tblContacts" where audit_id = r.audit_id) THEN
   ...

Ca économise une instruction et une variable et ça marchera dans tous les cas de figure.


@DanielVerite

Hors ligne

#6 20/02/2017 10:31:11

Re : execute into

Un grand merci ?

et le if not found marchera ?

Hors ligne

#7 20/02/2017 15:09:49

dverite
Membre

Re : execute into

FOUND utilisé comme en #4 fonctionne bien, mais ne pas oublier que FOUND est multi-usage.
La doc: http://docs.postgresql.fr/9.6/plpgsql-statements.html indique toutes les règles qui s'appliquent et certaines sont assez baroques (la boucle FOR par ex.)

La variable FOUND est initialisée à false au début de chaque fonction PL/pgSQL. Elle est positionnée par chacun des types d'instructions suivants :

    Une instruction SELECT INTO positionne FOUND à true si une ligne est affectée, false si aucune ligne n'est renvoyée.

    Une instruction PERFORM positionne FOUND à true si elle renvoie une ou plusieurs lignes, false si aucune ligne n'est produite.

    Les instructions UPDATE, INSERT, et DELETE positionnent FOUND à true si au moins une ligne est affectée, false si aucune ligne n'est affectée.

    Une instruction FETCH positionne FOUND à true si elle renvoie une ligne, false si aucune ligne n'est renvoyée.

    Une instruction MOVE initialise FOUND à true si elle repositionne le curseur avec succès. Dans le cas contraire, elle le positionne à false.

    Une instruction FOR ou FOREACH initialise FOUND à la valeur true s'il itère une ou plusieurs fois, et à false dans les autres cas. FOUND est initialisé de cette façon quand la boucle se termine : pendant l'exécution de la boucle, FOUND n'est pas modifié par la boucle, bien qu'il pourrait être modifié par l'exécution d'autres requêtes dans le corps de la boucle.

    Les instructions RETURN QUERY et RETURN QUERY EXECUTE mettent à jour la variable FOUND à true si la requête renvoie au moins une ligne, et false si aucune ligne n'est renvoyée.

Les autres instructions PL/pgSQL ne changent pas l'état de FOUND. Notez que la commande EXECUTE modifie la sortie de GET DIAGNOSTICS mais ne change pas FOUND.


@DanielVerite

Hors ligne

#8 20/02/2017 15:20:53

Re : execute into

un grand merci pour toutes ces précisions qui tombent à pic.
A plus

Hors ligne

Pied de page des forums