Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Firebird Discussion :

Simulation INSERT IGNORE avec WHEN SQLCODE -803 DO


Sujet :

SQL Firebird

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    novembre 2003
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : novembre 2003
    Messages : 109
    Points : 108
    Points
    108
    Par défaut Simulation INSERT IGNORE avec WHEN SQLCODE -803 DO
    Bonjour,

    Je voudrais simuler le comportement de l'instruction INSERT IGNORE de MySQL dans Firebird.

    J'ai une table qui contient un id auto incrémenté et 2 champs entier, value_A et value_B. J'ai définie une contrainte d'unicité sur {valeur_A , valeur_B}.

    Le comportement souhaité est le suivant :
    J’insère respectivement les valeurs 2 et 5 dans les champs valeur_A et valeur_B et je retourne l'id créé. Si la requête provoque une violation de la contrainte d'unicité (erreur 803), alors je sélectionne l'id dont les champs valeur_A et valeur_B valent respectivement 2 et 5.

    Concrètement, j'en arrives à la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    EXECUTE block AS BEGIN
        INSERT
        INTO "table"(
            "valeur_A", 
            "valeur_B"
        )VALUES(
            2, 
            5
        )RETURNING "id";
        WHEN SQLCODE -803 DO
            SELECT "id"
            FROM "table"
            WHERE "valeur_A"=2
            AND "valeur_B"=5;
    END
    Problème, il me dit
    "SQL error code = -104. Token unknown - line 14, column 27. ;."
    Et je ne comprends pas pourquoi il me dit que le dernier ; est invalide (et si je l'enlève, il me dit que c'est END qui est invalide, ce qui me parait logique).


    Merci ^^

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique
    Inscrit en
    janvier 2007
    Messages
    11 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : janvier 2007
    Messages : 11 262
    Points : 29 184
    Points
    29 184
    Billets dans le blog
    29
    Par défaut
    Bonjour,

    Ce qui me choque : l'utilisation des " " normalement inutiles, le fait que si le bloc doit renvoyer des données il n'y ait pas de déclaration en ce sens (RETURNS) et qu'il n'y ait pas de SUSPEND

    Pour en avoir le cœur net j'ai donc créé la table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE TEST_1
    (
      ID Bigint NOT NULL,
      COLA Integer NOT NULL,
      COLB Integer NOT NULL,
      PRIMARY KEY (ID),
      CONSTRAINT UNQ_TEST_1_1 UNIQUE (COLA,COLB)
    );
    et testé ce bloc (fonctionnel, avec flamerobin)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    SET TERM $ ;
    EXECUTE BLOCK RETURNS (PID BIGINT)
    AS BEGIN
    INSERT INTO TEST_1(COLA,COLB) VALUES (2,5) RETURNING ID INTO :PID;
    SUSPEND;
    WHEN SQLCODE -803 DO
      begin
            SELECT id  FROM TEST_1 WHERE COLA=2 AND COLB=5 INTO :PID;     
            SUSPEND;
      end      
    END$
    SET TERM ; $
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    novembre 2003
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : novembre 2003
    Messages : 109
    Points : 108
    Points
    108
    Par défaut
    Pour les guillemets, c'est parce que le driver PHP capitalise automatiquement les noms de tables et champs alors qu'ils sont en minuscules dans la base. Donc je suis obligé de les protéger à l'écriture de la requête. Et j'ai pas pensé à les retirer pour l'exemple.

    Effectivement, en rajoutant la déclaration de retours et l'instruction SUSPEND, ça fonctionne mieux ^^

    Je m'étais essentiellement basé sur cet article qui utilises des SELECT sans utiliser de RETURN, du coup je me suis dit que ça devait être implicite en P-SQL. Manque d’expérience, quoi.

    Au final, la requête donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    EXECUTE block RETURNS (id INTEGER) AS BEGIN
        INSERT
        INTO "table"(
            "valeur_A", 
            "valeur_B"
        )VALUES(
            2, 
            5
        )RETURNING "id" INTO :id;
        SUSPEND;
     
        WHEN SQLCODE -803 DO BEGIN
            SELECT "id"
            FROM "table"
            WHERE "valeur_A"=2
            AND "valeur_B"=5 INTO :id;
            SUSPEND;
        END
    END
    J'ai dû retirer les lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SET TERM $ ; et $ SET TERM ; $
    qui ne semblaient pas être reconnues.


    Merci pour la réponses (et au modo pour avoir ajouter les balises idoine ^^').

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requête d'insertion multiple avec 1 valeur fixe
    Par [DreaMs] dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/12/2005, 10h28
  2. [XHTML][CSS] simuler des frames avec des div
    Par piwai dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 09/11/2005, 14h26
  3. INSERT INTO avec une valeur numéroauto
    Par priest69 dans le forum Requêtes et SQL.
    Réponses: 12
    Dernier message: 08/11/2005, 16h39
  4. Simuler Vue modifiable avec postgresql
    Par mijoya dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 04/04/2005, 17h48
  5. INSERT multiples avec : rs.AddNew et .Update
    Par M.Zip dans le forum ASP
    Réponses: 4
    Dernier message: 03/12/2004, 16h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo