IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Bases de données Delphi Discussion :

Problème avec un Insert et valeur par default


Sujet :

Bases de données Delphi

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 62
    Par défaut Problème avec un Insert et valeur par default
    Bonjour,
    le contexte, je développe une appli en Delphi 7 et Interbase 6, je ne connaissais pas interbase alors j'y suis aller petit à petit. Après plusieurs essais, je me débrouille avec les générateurs, les procédures stockées, et les composants dans delphi tel les lookupcombobox, dbgrid et autres.

    voilà mon problème, tout aller bien, j'essai de faire quelque chose de trés simple et ... c'est le drame. je change deux colonnes d'une table pour mettre un contrainte "not null" et une valeur par défaut. Cela pour me permettre de rajouter un champ qui est la concaténation des deux autres (donc ces 2 champs ne doivent pas être null).

    Seulement la requête avec le mot Default ne fonctionne pas. Quelqu'un saurait-il m'expliquer ?

    en simplifiant au maximun et en utilisant directment IB Console, le code suivant ne fonctionne pas !!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    DROP TABLE "T_CLIENT";
    CREATE TABLE "T_CLIENT"
    (
      "CCLI_ID"	INTEGER NOT NULL,
      "CCLI_NOM"	VARCHAR(50) DEFAULT 'NC' NOT NULL,
      "CCLI_PRENOM"	VARCHAR(50) DEFAULT 'NC' NOT NULL,
      "CCLI_FULLNAME"	 COMPUTED BY ("CCLI_NOM" || ' ' || "CCLI_PRENOM"),
    CONSTRAINT "CCLI_ID" PRIMARY KEY ("CCLI_ID")
    );
    INSERT INTO T_CLIENT (CCLI_ID, CCLI_NOM, CCLI_PRENOM) VALUES (1, 'MON_NOM', DEFAULT);
    J'obtiens une erreur :

    Dynamic SQL Error
    SQL error code = -104
    Token unknown - line 1, char 76
    DEFAULT
    Statement: INSERT INTO T_CLIENT (CCLI_ID, CCLI_NOM, CCLI_PRENOM) VALUES (1, 'MON_NOM', DEFAULT)

  2. #2
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    Salut

    La valeur par défaut sera insérée dès lors que tu ne précise pas de valeur pour le champ:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    INSERT INTO T_CLIENT (CCLI_ID, CCLI_NOM) VALUES (1, 'MON_NOM');
    Voilou,

    @+ Claudius

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 62
    Par défaut
    Merci, pour cette réponse effectivement ceci fonctionne, mais est-il possible de faire la requete en utilisant le mot défaut, car mon but final est de pouvoir ne faire qu'une requête dans delphi construite de la maniére suivante:

    je récupère une valeur par un TEDIT, et je fait

    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
     
    //récupération du nom
    if EditNom.Text = '' then sNom:= 'Default'
    else sNom:= '''' + StringReplace(sNom, '''', '''''', [rfReplaceAll]) + '''';
     
    //récupération du prénom
    if EditPrenom.Text = '' then sPrenom:= 'Default'
    else sPrenom:= '''' + StringReplace(sNom, '''', '''''', [rfReplaceAll]) + '''';
     
    //création requete
    requete:= 'INSERT INTO T_CLIENT (CCLI_ID, CCLI_NOM, CCLI_PRENOM)'
     + ' VALUES (GEN_ID("GEN_CLIENT_ID", 1), ' + sNom + ', ' + sPrenom + ')';
     
    //appel le IBSQL pour insertion
    dataModule1.Insert(requete);

  4. #4
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    Salut

    Bon j'ai 'révisé' un peu ton code.

    1° remarque: Utilise QuotedStr, cette fonction double automatiquement les quotes (') de la chaîne.

    2° remarque: J'ai retiré l'insertion de CCLI_ID, car je suppose que tu as créé un trigger lié à un générateur dans ta base.

    Et enfin je ne saisi pas ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //appel le IBSQL pour insertion
    dataModule1.Insert(requete);
    Essaye comme ceci:
    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
    20
    21
    22
    23
    24
    25
     
    const
      requete = 'INSERT INTO T_CLIENT (CCLI_NOM, CCLI_PRENOM) ' +
                'VALUES (:NOM, :PRENOM)';
    begin
      with DataModule1.IBSQL1 do
      begin
        //Assignation de la requête au TIBSQL;
        SQL.Text := requete;
     
        // Nom
        if Trim(EditNom.Text) <> '' then
          ParamByName('NOM').AsString := QuotedStr(EditNom.Text)
        else
          ParamByName('NOM').IsNull := True;
        // Prénom
        if Trim(EditPrenom.Text) <> '' then
          ParamByName('PRENOM').AsString := QuotedStr(EditPrenom.Text)
        else
          ParamByName('PRENOM').IsNull := True;
     
        // appel le IBSQL pour insertion
        ExecQuery;
      end;
    end;
    @+ Claudius

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 62
    Par défaut
    Bon j'ai 'révisé' un peu ton code.

    1° remarque: Utilise QuotedStr, cette fonction double automatiquement les quotes (') de la chaîne.

    2° remarque: J'ai retiré l'insertion de CCLI_ID, car je suppose que tu as créé un trigger lié à un générateur dans ta base.

    Et enfin je ne saisi pas ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    //appel le IBSQL pour insertion
    dataModule1.Insert(requete);
    1°, Merci bien, en voilà une remarque qu'elle est judicieuse, je ne connaissais pas cette fontion et effectivment ça me paraît mieux pour le code.

    2°, Non, j'ai bien un générateur mais je n'ai pas de trigger, j'ai une procédure stockée car j'ai besoin de connaître l' ID client que je rentre, j'appelle donc cette procédure avant l'insertion, je récupére l'ID dans une variable entiére, et je fait l'insertion avec CCLI_ID.

    3°, En fait c'est une fonction de mon dataModule, j'ai fait 3 fonctions assez similaire pour gérer insertion, sélection et update. Ces fonctions sont assez générales et je les utilise presque pour toutes mes tables (est-ce dangeureux ou non ?), je trouve cela assez simple comme ça.
    exemple:
    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
    20
    21
    22
    function TDataModule1.Insert(instruction: string): boolean;
    begin
     try
        IBSQLInsert.Close;
        IBSQLInsert.SQL.Clear;
        IBSQLInsert.SQL.Add(instruction);
         try
        IBSQLInsert.ExecQuery;
        if not  IBSQLInsert.Prepared then  IBSQLInsert.Prepare;
        IBSQLInsert.transaction.CommitRetaining;
        result:=True;
        except
        if IBSQLInsert.transaction.InTransaction then
           begin
          IBSQLInsert.transaction.Rollback;
           result:=False;
           end;
        end;
        finally
        IBSQLInsert.Close;
        end;
    end;
    Je n'utilise donc pas la propriété ParamByName du TIBSQL (cela m'arrive mais que pour les blobs et j'en ai trés peu) et c'est pour cette raison que je cherches à faire une requête SQL pure.

    J'ai trouvé cette solution mais je trouve qu'elle me complique un peu la vie, j'aurais préféré utilisé directement 'DEFAULT'.

    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
    20
    21
    22
    23
    24
    25
     
    //génére l'id client
    DataModule1.Select('SELECT NEW_CLIENT_ID FROM CLIENT_AUTOINC');
    idClient:= DataModule1.IBSQLSelect.FieldByName('NEW_CLIENT_ID').AsInteger;
    DataModule1.IBSQLSelect.Close;
     
    rqClCol:= 'CCLI_ID';
    rqClVal:= IntToStr(idClient);
     
    //récupération du nom
    if EditNom.Text <> '' then
    begin
     rqClCol:= rqClCol + ', CCLI_NOM';
     rqClVal:= rqClVal + ', ''' + QuotedStr(EditNom.Text) + '''';
    end;
     
    //récupération du prénom
    if EditPrenom.Text <> '' then
    begin
     rqClCol:= rqClCol + ', CCLI_PRENOM';
     rqClVal:= rqClVal + ', ''' + QuotedStr(EditPrenom.Text) + '''';
    end;
     
    //requete d'insertion
    DataModule1.Insert('INSERT INTO T_CLIENT (' + rqClCol + ') VALUES (' + rqClVal + ')');

  6. #6
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    Citation Envoyé par jaffael Voir le message
    3°, En fait c'est une fonction de mon dataModule, j'ai fait 3 fonctions assez similaire pour gérer insertion, sélection et update. Ces fonctions sont assez générales et je les utilise presque pour toutes mes tables (est-ce dangeureux ou non ?), je trouve cela assez simple comme ça.
    Dangereux non, simplement je n'avais pas saisi que c'était une fonction implémentée dans le DataModule.

    Une nouvelle remarque sur ta fonction Insert.
    Faire un Prepare après l'ExecQuery ne sert à rien, il faut effectuer le Prepare juste avant l'ExecQuery. Le Prepare va vérifier entre autres la présence et la définition des paramètres de la requête.

    Citation Envoyé par jaffael Voir le message
    J'ai trouvé cette solution mais je trouve qu'elle me complique un peu la vie, j'aurais préféré utilisé directement 'DEFAULT'.
    Malheureusement pas de mot clé DEFAULT ou terme similaire que tu pourrais transmettre à ta requête.

    @+

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    62
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 62
    Par défaut
    Trés bien, merci Cl@udius, finalement ma solution me paraît correcte, bien que ce soit bien plus compliqué pour mon appli (j'ai simplifié pour le post en ne mettant que ID, nom , prenom).

    C'est dommage, j'aurais aimé comprendre (j'aime bien comprendre quand ça ne marche pas même si je trouve d'autres solutions, ça renseigne beaucoup sur le fonctionnement des objets) pourquoi interbase n'accepte pas les requête avec le mot "DEFAULT".

    En fait, j'avoue que pour le "Prepare", je ne savais pas trop, j'ai récupéré l'insert sur un tutoriel Interbase.

    Merci beaucoup de ton aide .

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

Discussions similaires

  1. Problème avec l'insertion de la valeur 0
    Par sab_info dans le forum Excel
    Réponses: 4
    Dernier message: 21/04/2013, 19h42
  2. Input Password Avec Valeur Par Default
    Par xxkirastarothxx dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 29/09/2009, 17h43
  3. Problème valeur par default de l'include
    Par ptifou78 dans le forum Langage
    Réponses: 6
    Dernier message: 06/09/2009, 17h44
  4. Problème avec un INSERT
    Par nnj dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 01/08/2006, 15h51
  5. [MFC] problème avec les insertions dans CComboBox
    Par Joeleclems dans le forum MFC
    Réponses: 12
    Dernier message: 11/06/2004, 15h31

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