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

Lazarus Pascal Discussion :

Ma requête SQL DELETE ne fonctionne pas [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut Ma requête SQL DELETE ne fonctionne pas
    Bonjour,

    Dans mon programme, j'interroge ma base de données avec des requêtes de type SELECT. Jusque là tout va bien.
    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
      // Initialisation de la base de données
      IHM_FenetrePrincipale.IHM_DbSqliteConnection.DatabaseName:= DB_FileName;
      IHM_FenetrePrincipale.IHM_DbSqliteConnection.Connected := True;
      IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Clear;
      // Requete sql pour obtenir tous les Noms
      IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Add('SELECT DISTINCT "Nom" FROM table ORDER BY "Nom" ASC');
      IHM_FenetrePrincipale.IHM_DbSqliteQuery.ExecSQL;
      IHM_FenetrePrincipale.IHM_DbSqliteQuery.Active:= true;
     
      // Ajout des noms dans le chklistbox
      while not IHM_FenetrePrincipale.IHM_DbSqliteQuery.EOF do
      begin
        IHM_FenetrePrincipale.IHM_ChklistboxNom.Items.Add(IHM_FenetrePrincipale.IHM_DbSqliteQuery.FieldByName('Nom').AsString);
        IHM_FenetrePrincipale.IHM_DbSqliteQuery.Next;
      end;
     
      // Fermeture de la base de données
      IHM_FenetrePrincipale.IHM_DbSqliteQuery.Close;
      IHM_FenetrePrincipale.IHM_DbSqliteConnection.Close;
    Par contre, lorsque j'essaie de faire une requête de type DELETE, là je coince.
    Je n'ai pas de message d'erreur et aucun enregistrement n'est effacé.
    La requête que j'envoie fonctionne très bien avec SQLITEMAN
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
              req := req + '"' + tag_checked[i] + '"';
              // Initialisation de la base de données pour requete
              IHM_FenetrePrincipale.IHM_DbSqliteConnection.DatabaseName:= DB_FileName;
              IHM_FenetrePrincipale.IHM_DbSqliteConnection.Connected := True;
              IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Clear;
              // Execution de la requete
              IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Add(req);
              IHM_FenetrePrincipale.IHM_DbSqliteQuery.Prepare;
              ShowMessage(req);
              IHM_FenetrePrincipale.IHM_DbSqliteQuery.ExecSQL;
              // Fermeture de la base de données
              IHM_FenetrePrincipale.IHM_DbSqliteQuery.Close;
              IHM_FenetrePrincipale.IHM_DbSqliteConnection.Close;

  2. #2
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 951
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 951
    Points : 5 671
    Points
    5 671
    Par défaut
    Koa,

    Vu ton code, ta requête est dans le brouillard :

    Comment veux-tu qu'on sache ce qui résulte de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    req := req + '"' + tag_checked[i] + '"';

  3. #3
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Citation Envoyé par droggo Voir le message
    Comment veux-tu qu'on sache ce qui résulte de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    req := req + '"' + tag_checked[i] + '"';
    La requête que j'envoie fonctionne très bien avec SQLITEMAN
    Oups, la requete que j'envoie ressemble à ceci :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    DELETE FROM "tag" WHERE "Tag_name"="tintin"

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    248
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 248
    Points : 538
    Points
    538
    Par défaut
    Bonsoir,

    Si "tintin" est une chaîne de caractères, ne devrait-il pas être encadré que de simples cotes. (doublées dans le texte en Pascal=>+'''' et non +'"')

    André

  5. #5
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    En mode SELECT je passe ma requête avec les guillemets (")
    Cela fonctionne impeccable. C'est pourquoi je me disait qu'en mode DELETE je pouvais aussi utiliser les guillemets.

    J'ai quand même essayé ma requête DELETE les simples quotes comme vous me l'avez conseillé ; cela ne change rien.

    Je ne sais pas si mon problème provient de ma requête DELETE (qui fonctionne quand je la passe en manuel dans SQLITEMAN) ou si j'ai oublié une instruction quelconque avant et/ou après EXECSQL.

    NB : Lorsque je passe la requête DELETE avec les simples quotes dans SQLITEMAN, il me retourne REQUÊTE OK sans pour autant supprimer l'enregistrement. Et avec les guillemets, REQUETE OK avec la suppression de l'enregistrement.

    Par désespoir, je regarde du coté des transactions.
    Je suis complètement bloqué

  6. #6
    Membre habitué

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2006
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2006
    Messages : 58
    Points : 195
    Points
    195
    Par défaut
    Bonjour

    Lorsque j'ai commencé a faire du dev SQL avec lazarus, je rajoutais moi aussi les double quote à la main, et très souvent mes requêtes n’aboutissaient pas.

    C'est alors que la lumière m'est apparue dans un exemple avec la fonction QuotedStr() qui te retourne la chaine entourée de simple quote pour formater tes requêtes correctement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    req := req + QuotedStr(tag_checked[i]);
    Ce qui au final donnerait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DELETE FROM tag WHERE tag_name='tintin'
    sans les double quote autour des champs et nom de table

    bon courage

  7. #7
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 68
    Points : 69
    Points
    69
    Par défaut
    si je comprends bien quand tu fait une requête SQL de type DELETE rien ne se passe.

    Fait tu un ApplyUpdate après ton instruction DELETE ?

    Ta base est SQLITE n'est ce pas ?

  8. #8
    Membre du Club
    Inscrit en
    Novembre 2006
    Messages
    81
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 81
    Points : 52
    Points
    52
    Par défaut
    Lorsque je fait APPLYUPDATE juste après EXECSQL, il me retourne une erreur :
    Operation cannot be performed on an inactive dataset.

    C'est bien une base SQLITE3 que j'utilise.
    La table ne contient que 1 colonne "Tag_name", sans index ni clé ni rien du tout. La colonne "Tag_name" est de type string.

    Merci aussi pour l'astuce "QuotedStr".

    Merci de votre aide je suis certain que mon problème va etre résolu.
    Et que c'est juste un détail...
    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
    uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
      StdCtrls, CheckLst, eventlog, sqlite3conn, sqldb, db, types; 
     
     
    req := req + QuotedStr(tag_checked[i]);
    // DELETE FROM tags WHERE Tag_name='Tintin'
            // Initialisation de la base de données pour requete
            IHM_FenetrePrincipale.IHM_DbSqliteConnection.DatabaseName:= DB_FileName;
            IHM_FenetrePrincipale.IHM_DbSqliteConnection.Connected := True;
            IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Clear;
            // Execution de la requete
            IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Add(req);
            ShowMessage(req);
            IHM_FenetrePrincipale.IHM_DbSqliteQuery.ExecSQL;
            IHM_FenetrePrincipale.IHM_DbSqliteQuery.ApplyUpdates;
            // Fermeture de la base de données
            IHM_FenetrePrincipale.IHM_DbSqliteQuery.Close;
            IHM_FenetrePrincipale.IHM_DbSqliteConnection.Close;

  9. #9
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 68
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par ulysse_31 Voir le message
    Lorsque je fait APPLYUPDATE juste après EXECSQL, il me retourne une erreur :
    Operation cannot be performed on an inactive dataset.
    Il faudrait que tu vérifie l'état de ton Dataset lors de ton ApplyUpdate. ta requete doit être certainement fermée avant.

    Pour SQLITE3 j'utilise la Zeos Access 7.0 pour programmer.
    Avec c'est bien plus simple, c'est multi environnement. (Delphi, C++ et autre)

    Pour accéder à une table je pose une ZConnection, une ZTable et un datasource .

    Avec Zeos access 7.O ta suppression ressemblerait à
    ZTable1.Delete;
    et pis c'est tout...

    Donc, Dans ton cas plus besoin de
    DELETE FROM tag WHERE tag_name='tintin'
    ni de
    'SELECT DISTINCT "Nom" FROM table ORDER BY "Nom" ASC'
    Avec Zeos c'est plus simple.

    Pour chercher une un record c'est par exemple
    if ZTable1.Locate(laCle, Ma valeur, Mes options)= true then ....;
    Jazz

  10. #10
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Points : 5 918
    Points
    5 918
    Par défaut
    Bonjour,
    Citation Envoyé par ulysse_31 Voir le message
    C'est bien une base SQLITE3 que j'utilise.
    La table ne contient que 1 colonne "Tag_name", sans index ni clé ni rien du tout. La colonne "Tag_name" est de type string.
    Ok...
    Je suppose que vous utilisez les composants de base fournis avec Lazarus à savoir : TSQLite3Connection, TSQLQuery et TSQLTransaction.
    Mais, je ne vois pas de validation de transaction dans votre code....

    En nettoyant un peu le tout, on devrait avoir :
    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
      req := req + QuotedStr(tag_checked[i]);
      // DELETE FROM tags WHERE Tag_name='Tintin'
      // Initialisation de la base de données pour requete
      IHM_FenetrePrincipale.IHM_DbSqliteConnection.DatabaseName:= DB_FileName;
      // Ouverture de la base de données
      IHM_FenetrePrincipale.IHM_DbSqliteConnection.Connected := True;
      try
        // Préparation de la requête
        IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Clear;
        IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Add(req);
        ShowMessage(req);
        // Execution de la requete
        IHM_FenetrePrincipale.IHM_DbSqliteQuery.ExecSQL;
        // Validation de la transaction
        // Je suppose que le composant de transaction rattaché à celui de connexion
        // s'appelle IHM_DbTransaction et est de type TSQLTransaction
        IHM_FenetrePrincipale.IHM_DbTransaction.Commit;
        // "Fermeture" de la requête inutile car il ne s'agit pas d'une requête de sélection
        // IHM_FenetrePrincipale.IHM_DbSqliteQuery.Close;
      finally
        // Fermeture de la base de données
        IHM_FenetrePrincipale.IHM_DbSqliteConnection.Close;
      end;

  11. #11
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 68
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par Ph. B. Voir le message
    Bonjour,
    Ok...
    Je suppose que vous utilisez les composants de base fournis avec Lazarus à savoir : TSQLite3Connection, TSQLQuery et TSQLTransaction.
    Mais, je ne vois pas de validation de transaction dans votre code....

    En nettoyant un peu le tout, on devrait avoir :
    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
      req := req + QuotedStr(tag_checked[i]);
      // DELETE FROM tags WHERE Tag_name='Tintin'
      // Initialisation de la base de données pour requete
      IHM_FenetrePrincipale.IHM_DbSqliteConnection.DatabaseName:= DB_FileName;
      // Ouverture de la base de données
      IHM_FenetrePrincipale.IHM_DbSqliteConnection.Connected := True;
      try
        // Préparation de la requête
        IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Clear;
        IHM_FenetrePrincipale.IHM_DbSqliteQuery.SQL.Add(req);
        ShowMessage(req);
        // Execution de la requete
        IHM_FenetrePrincipale.IHM_DbSqliteQuery.ExecSQL;
        // Validation de la transaction
        // Je suppose que le composant de transaction rattaché à celui de connexion
        // s'appelle IHM_DbTransaction et est de type TSQLTransaction
        IHM_FenetrePrincipale.IHM_DbTransaction.Commit;
        // "Fermeture" de la requête inutile car il ne s'agit pas d'une requête de sélection
        // IHM_FenetrePrincipale.IHM_DbSqliteQuery.Close;
      finally
        // Fermeture de la base de données
        IHM_FenetrePrincipale.IHM_DbSqliteConnection.Close;
      end;
    Bonsoir Philippe

    Dans le cas d'Ulysse31, je ne vois pas l’intérêt de l'utilisation de transaction pour un seule table avec un seul champs ....

    Jazz

  12. #12
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 218
    Points : 41 483
    Points
    41 483
    Billets dans le blog
    63
    Par défaut
    @Jazz77 de mon point de vue ton utilisation des ZEOSDBO est incorrecte , certainement de vieux réflexe BDE qui trainent .
    Ouvrir une table entière , surtout en lecture/écriture , chercher l'enregistrement pour le supprimer est très "consommateur" . L'utilisation d'un SQL pour supprimer un enregistrement est beaucoup plus rapide/efficace .
    De plus ton "Table1.Delete;" n'efface que l'enregistrement en cours ! pas un ensemble .

    N'oublions pas que par défaut également que les ZEOSDBO sont en autocommit par défaut


    avec une TZReadOnlyQuery (ZROQ) posé sur une forme

    Code méthode 1 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ZROQ.SQL.Text:='DELETE FROM TAG WHERE TAG_NAME=:TN';
    ZROQ.ParamByName('TN').asString:='tintin';
    ZROQ.ExecSQL;

    Code méthode 2 , variante création Query à la volée : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    var ZROQ : TZReadonlyQuery;
    begin
     ZROQ:=TZReadOnlyQuery.Create(null);
    try
     ZROQ.Connection:=ZConnection1;
    ZROQ.SQL.Text:='DELETE FROM TAG WHERE TAG_NAME=:TN';
    ZROQ.ParamByName('TN').asString:='tintin';
    ZROQ.ExecSQL;
    finally
      ZROQ.Free;
    end;

    Code méthode 3 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    // simple
    Connection.ExecuteDirect('DELETE FROM TAG WHERE TAG_NAME='+QuotedStr('tintin')); 
    // plus travaillée
    Connection.ExecuteDirect(Format('DELETE FROM TAG WHERE TAG_NAME=%s',[QuotedStr('tintin')]));
    // en raffinement on peut utiliser l'autre forme de ExecuteDirect pour obtenir le nombre de suppression
    var  ns : integer;
    begin
    if Connection.ExecuteDirect(Format('DELETE FROM TAG WHERE TAG_NAME=%s',[QuotedStr('tintin')]),i) then
    Showmessage(Format('%d Suppression(s)',[i])
    else Showmessage('je me suis planté');

  13. #13
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 68
    Points : 69
    Points
    69
    Par défaut
    Bonjour Serge,

    @Jazz77 de mon point de vue ton utilisation des ZEOSDBO est incorrecte , certainement de vieux réflexe BDE qui trainent .
    Pour ma culture personnel, si tu pouvais développer ton argumentation, cela serait bien.

    Ouvrir une table entière , surtout en lecture/écriture , chercher l'enregistrement pour le supprimer est très "consommateur" . L'utilisation d'un SQL pour supprimer un enregistrement est beaucoup plus rapide/efficace .
    En quoi chercher un enregistrement est il "consommateur" ?
    Temps ? (combien de millisecondes en plus ?)
    Mémoire ? combien d'Octets en plus ?

    Je pense que l'on parle d'un base mono-poste en locale . Alors les performances temps d’accès et mémoire ne sont pas forcément déterminant...

    De plus ton "Table1.Delete;" n'efface que l'enregistrement en cours ! pas un ensemble .
    Complétement d'accord avec toi.
    Dans le cas d'ulysse31 il n'est pas mentionné de supprimer un ensemble d'enregistrements.

    Jazz

  14. #14
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Points : 5 918
    Points
    5 918
    Par défaut
    Bonjour Jazz77,
    Citation Envoyé par Jazz77 Voir le message
    Dans le cas d'Ulysse31, je ne vois pas l’intérêt de l'utilisation de transaction pour un seule table avec un seul champs ....
    C'est assez inquiétant ce que vous dites là , même pour une table avec une seule colonne. Les transactions sont un des fondements de tout SGBD qui se respecte : A quoi servent les transactions ?
    D'autre part, le composant TSQLQuery ne peut se passer d'un composant TSQLTransaction.
    Mais bon vaut mieux un petit exemple qu'un long discours. Prenez la base et la table décrite par Ulysse31, créez une application Lazarus avec les composants adéquats, un composant TButton pour tester le code suivant, une fois avec l'instruction désactivée, une fois sans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      SQLite3Connection1.Connected := True;
      try
        SQLQuery1.SQL.Text := 'DELETE FROM TAG WHERE TAG_NAME = ' + QuotedStr('tintin');
        SQLQuery1.ExecSQL;
        //SQLTransaction1.Commit;
      finally
        SQLite3Connection1.Connected := False;
      end;
    end;
    Et surveillez le contenu de la table TAG depuis Sqlite Manager...

  15. #15
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 68
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par Ph. B. Voir le message
    Bonjour Jazz77,C'est assez inquiétant ce que vous dites là , même pour une table avec une seule colonne. Les transactions sont un des fondements de tout SGBD qui se respecte :
    Si mes souvenirs sont exacts, les transactions sont faite pour conserver l'intégrité d'un Base. Elle permettent dans le cas d'erreur de revenir à état stable à un instant T-1.
    Je ne remets pas cela en question bien évidement. C'est indispensable dans le cas d'opérations complexes ou en environnement mufti utilisateur.

    Mais la dans ce cas sur une base locale mono utilisateur sur une seule table et un seule enregistrement, ce n'est pas forcément utile de monopoliser des trésors de complexité et un florilège de code

    J'ai toujours entendu qu'il fallait éviter de complexifier du code inutilement et qu'il faut faire simple quand cela est préférable.

    Dans ce cas, à mes yeux un simple ZTable1.delete suffit et Zeos et Sqlite sait le faire très bien. Et il n'y a aucune inquiétude à avoir..

    Jazz

  16. #16
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Points : 5 918
    Points
    5 918
    Par défaut
    Citation Envoyé par Jazz77 Voir le message
    Si mes souvenirs sont exacts, les transactions sont faite pour conserver l'intégrité d'un Base. Elle permettent dans le cas d'erreur de revenir à état stable à un instant T-1.
    Je ne remets pas cela en question bien évidement. C'est indispensable dans le cas d'opérations complexes ou en environnement mufti utilisateur.
    Vision trop restreinte de la problématique.
    Je cite Frédéric Brouard qui définit les transactions :
    Les transactions sont la clef même de toute problématique d'accès concurrent. Même lors de simples lectures, le SGBDR doit pouvoir assurer le respect de la cohérence des données dans le temps. Bien entendu, lors de modifications de données, les transactions servent à garantir que tout soit mené à bien sans qu'il en résulte la moindre anomalie, ou à l'inverse, si une anomalie se produit, de revenir à l'état antérieur, c'est à dire l'état qu'avaient les données avant le démarrage de la transaction.
    Au cas où vous l'auriez oublié, un accès concurrent peut se faire au sein d'une même application et ce même en lecture;
    Citation Envoyé par Jazz77 Voir le message
    Mais la dans ce cas sur une base locale mono utilisateur sur une seule table et un seule enregistrement, ce n'est pas forcément utile de monopoliser des trésors de complexité et un florilège de code
    d'autre part, je connais beaucoup d'utilisateurs qui vont lancer 2 fois une même application soi disant monoposte...

    Citation Envoyé par Jazz77 Voir le message
    J'ai toujours entendu qu'il fallait éviter de complexifier du code inutilement et qu'il faut faire simple quand cela est préférable.
    Vous avez raison, aussi vaut-il mieux une instruction "DELETE FROM" transactionnée à plusieurs opérations "Locate", "Delete" qui elles même vont générer de multiples accès à la base de données, voire de multiples transactions !
    Citation Envoyé par Jazz77 Voir le message
    Dans ce cas, à mes yeux un simple ZTable1.delete suffit et Zeos et Sqlite sait le faire très bien. Et il n'y a aucune inquiétude à avoir..
    Comme l'a dit @SergioMaster, il s'agit d'une approche BDE du temps des bases de données orientées fichiers (paradox pour ne pas le citer), et pas de l'approche que l'on doit avoir pour lire et écrire les données d'une base, même en mono-utilisateur.

  17. #17
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 68
    Points : 69
    Points
    69
    Par défaut
    Citation Envoyé par Ph. B. Voir le message
    Vision trop restreinte de la problématique.
    Je cite Frédéric Brouard qui définit les transactions :

    Au cas où vous l'auriez oublié, un accès concurrent peut se faire au sein d'une même application et ce même en lecture;
    d'autre part, je connais beaucoup d'utilisateurs qui vont lancer 2 fois une même application soi disant monoposte...


    Vous avez raison, aussi vaut-il mieux une instruction "DELETE FROM" transactionnée à plusieurs opérations "Locate", "Delete" qui elles même vont générer de multiples accès à la base de données, voire de multiples transactions !

    Comme l'a dit @SergioMaster, il s'agit d'une approche BDE du temps des bases de données orientées fichiers (paradox pour ne pas le citer), et pas de l'approche que l'on doit avoir pour lire et écrire les données d'une base, même en mono-utilisateur.
    Sauf que dans votre raisonnement, vous oubliez que les applications orientés "Fichiers" marchaient plutôt pas mal même.


    Quelque soit l'approche orienté "Fichiers" ou SGBD, si une application est robuste, bien documenté et maintenable facilement, c'est l'essentiel.

    Bien sur qu'un accès concurrent peut se faire sur en locale.
    Cela se gère.
    On peut aussi écrire une application mono instance bien écrite , cela se fait bien aussi.

    Je suis d'accord qu'un "DELETE FROM" est bien plus efficace que plusieurs locate, delete, mais cela n'a jamais été mon propos ici

    Jazz

  18. #18
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 218
    Points : 41 483
    Points
    41 483
    Billets dans le blog
    63
    Par défaut
    Dans mon post , je ne prenais pas en compte une approche mono-poste .
    De toute façon une approche multi-utilisateur (voire réseau) même dans le cas d'une application monoposte n'est pas moins robuste .
    Autant prendre de bonnes habitudes

  19. #19
    Expert confirmé
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    Avril 2002
    Messages
    1 786
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 786
    Points : 5 918
    Points
    5 918
    Par défaut
    Citation Envoyé par Jazz77 Voir le message
    Sauf que dans votre raisonnement, vous oubliez que les applications orientés "Fichiers" marchaient plutôt pas mal même.
    Ben voyons, mais au prix d'un florilège de codes (je vous cite) !

    Par analogie, les avions commerciaux à moteurs à piston marchaient plutôt pas mal aussi, mais ces derniers ont été remplacés par des turbines ou des turbo-réacteurs dont la fiabilité et les performances sont bien supérieures...
    Citation Envoyé par Jazz77 Voir le message
    Quelque soit l'approche orienté "Fichiers" ou SGBD, si une application est robuste, bien documenté et maintenable facilement, c'est l'essentiel.
    Et si elle est écrite en tenant compte du fonctionnement de ses différents éléments dont le moteur de base de données, c'est encore mieux...
    Citation Envoyé par Jazz77 Voir le message
    Bien sur qu'un accès concurrent peut se faire sur en locale.
    Cela se gère.
    Donc vous vous contredisez, plutôt que laisser faire le SGBD, vous préférez complexifier le code de l'application cliente pour aboutir au même résultat.
    Citation Envoyé par Jazz77 Voir le message
    On peut aussi écrire une application mono instance bien écrite , cela se fait bien aussi.
    Ca, c'est affectivement côté applicatif.
    Citation Envoyé par Jazz77 Voir le message
    Je suis d'accord qu'un "DELETE FROM" est bien plus efficace que plusieurs locate, delete, mais cela n'a jamais été mon propos ici
    Vous avez quand même prétendu le contraire précédemment, en préférant un ZTable1.Locate() et un ZTable1.Delete !
    De plus, utiliser une table plutôt qu'une requête est contre-performant en temps (même s'il s'agit de millisecondes) comme en ressources : il faut ouvrir la table (= rapatrier les lignes de cette table auprès de l'application), parcourir ces lignes, supprimer un enregistrement (= notifier la base de données)...
    Comme l'a rappelé @SergioMaster, autant prendre de bonnes habitudes, même pour une application mono-poste mono-instance, car qui dit qu'elle n'évoluera pas vers du multi ?

  20. #20
    Membre du Club
    Homme Profil pro
    retraité
    Inscrit en
    Février 2008
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autriche

    Informations professionnelles :
    Activité : retraité
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Février 2008
    Messages : 28
    Points : 59
    Points
    59
    Par défaut
    Bonjour,

    Le code ci-joint fonctionne chez moi sans problème.
    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
    26
     
    procedure TForm1.EffaceEnregistrement (NomTable : String ; ValCle : integer ) ;
    Var
    SQLQ_Tmp : TZQuery ;
    begin
       SQLQ_Tmp := TZQuery.Create(self);
       try
       SQLQ_Tmp.connection := ZConnection1 ;
     
       SQLQ_Tmp.SQL.Clear;
       SQLQ_Tmp.SQL.add('delete from ' + NomTable + ' where num = ' + IntToStr(ValCle )) ;
       SQLQ_Tmp.ExecSQL;
       finally
       SQLQ_Tmp.Free;
       end;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    begin
     
       // carnet est le nom de la table SQLite, 5 est la valeur de la clé de l'enregistrement à supprimer
       EffaceEnregistrement ('carnet' , 5 );
       ZTable1.Active:= false;
       ZTable1.Active := true ; // rafaichissement de l'affichage
     
    end;
    J'ai lu dans le fil que ta base n'est pas indexée, ce genre de blocage, j'ai déjà eu et cela m'avait couté quelques heures de travail.
    Essaye en créant une clé primaire.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Requête SQL qui ne fonctionne pas
    Par Soulama dans le forum Groovy
    Réponses: 1
    Dernier message: 25/04/2016, 03h49
  2. Interbase requête SQL qui ne fonctionne pas
    Par colorid dans le forum InterBase
    Réponses: 6
    Dernier message: 20/11/2007, 17h36
  3. requête match qui ne fonctionne pas.
    Par sam01 dans le forum Requêtes
    Réponses: 3
    Dernier message: 29/05/2006, 20h28
  4. [MySQL] Requête update qui ne fonctionne pas
    Par Sylvain245 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 05/12/2005, 16h40
  5. [SQL] Requête à jointure qui ne fonctionne pas
    Par Bensor dans le forum Langage SQL
    Réponses: 2
    Dernier message: 09/12/2004, 16h10

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