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

#1 08/06/2012 16:56:11

mderf
Membre

Problème d’exécution d’un progamme ecpg (postgresql 8.4.10 )

Problème d’exécution d’un programme ecpg  (postgresql 8.4.10 serveur red hat enterprise 5.3 64 bit ).

Bonjour,
J’ai un problème dû à la migration d’une base de données 8.2.4 vers 8.4.10.
Le problème se situe au niveau d’un programme C incluant du sql en un mot  ECPG
La  compilation du programme est OK.

Lors de l’exécution de mon programme j ai un bug :
         SQL error: syntax error at or near "$1" on line 367
         SQL error: too many arguments on line 368
         SQL error: invalid statement name "stmt_select_timestamp" on line 369


ci-dessous les lignes de code incriminées :
        EXEC SQL BEGIN DECLARE SECTION;
        /* calcul la date de creation du message dans la table */
      const char *select_timestamp = "SELECT ( now()- interval ? )::varchar";
        EXEC SQL END DECLARE SECTION;

    memset(timestamp_d,    '\0', TAILLE_BUFFER);
    memset(date,    '\0', TAILLE_BUFFER);
    sprintf(date,"    %s days",360);


    EXEC SQL WHENEVER SQLERROR SQLPRINT
      EXEC SQL PREPARE stmt_select_timestamp     FROM :select_timestamp;
    EXEC SQL EXECUTE stmt_select_timestamp     INTO :timestamp_d USING :date;
      EXEC SQL DEALLOCATE PREPARE stmt_select_timestamp;
      timestamp_d[11] = NUL;

Hors ligne

#2 08/06/2012 17:27:51

gleu
Administrateur

Re : Problème d’exécution d’un progamme ecpg (postgresql 8.4.10 )

Il me semble qu'il manque les guillemets autour du point d'interrogation. Cela étant dit, même si j'ai fait un peu d'ECPG, je suis loin d'être un expert.


Guillaume.

Hors ligne

#3 08/06/2012 21:42:26

dverite
Membre

Re : Problème d’exécution d’un progamme ecpg (postgresql 8.4.10 )

En version 8.2 ECPG injecte certainement  le paramètre dans la requête, sans utiliser le PREPARE côté serveur.
Mais depuis 8.3, ECPG utilise le PREPARE côté serveur (voir les notes de version de la doc).


Or le vrai PREPARE est strict sur ce qui peut être paramètre ou pas, en gros seuls les litéraux peuvent être des paramètres. DAYS étant  un mot clef et non un litéral, l'expression "360 DAYS" ne convient pas comme paramètre.

C'est un problème, les autres interfaces comme PDO ou DBD::Pg qui ont opté pour les PREPARE côté serveur ont le même.


La solution est de faire en SQL:

PREPARE stmt_X as SELECT ( now()- $1 * '1 day'::interval )::varchar

et de passer juste le nombre de jours dans le paramètre, sans "DAYS" évidemment.

Hors ligne

#4 11/06/2012 10:01:00

mderf
Membre

Re : Problème d’exécution d’un progamme ecpg (postgresql 8.4.10 )

Merci pour les informations et les précisions.

Pour la communauté, le code corrigé et testé a partir des informations données par Monsieur  "dverite".

EXEC SQL BEGIN DECLARE SECTION;
/* calcul la date de creation du message dans la table */
    const char *select_timestamp = "SELECT ( now()- ? * '1 day'::interval )::varchar";
EXEC SQL END DECLARE SECTION;

memset(timestamp_d,    '\0', TAILLE_BUFFER);
memset(date,    '\0', TAILLE_BUFFER);
sprintf(date,"%s",360);

EXEC SQL WHENEVER SQLERROR SQLPRINT
EXEC SQL PREPARE stmt_select_timestamp     FROM :select_timestamp;
EXEC SQL EXECUTE stmt_select_timestamp     INTO :timestamp_d USING :date;
EXEC SQL DEALLOCATE PREPARE stmt_select_timestamp;
timestamp_d[11] = NUL;

Hors ligne

Pied de page des forums