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 :

Requête paramétrée, variable selon conditions


Sujet :

Bases de données Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut Requête paramétrée, variable selon conditions
    Bonjour,

    Je coince sur un bête problème, j'ai besoin de mettre à jour 1 ou 2 champs sur une table, ce nombre étant fonction de la valeur de 2 variables...
    Un peu de code pour expliquer:

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    procedure TfrmMain.btnApplyPropertiesClick(Sender: TObject);
    var
      i1, iType, iWeight: Integer;
    begin
      if (not chkType.Checked) and (not chkWeight.Checked) then
        Exit;
     
      iType := -1;
      iWeight := -1;
      if chkType.Checked then
        iType := cbbType.ItemIndex + 1;
      if chkWeight.Checked then begin
        case cbbWeight.ItemIndex of
          0: iWeight := 20;
          1: iWeight := 30;
          2: iWeight := 40;
          3: iWeight := 50;
          4: iWeight := 60;
        end;
      end;
     
      with qry do begin
        SQL.Clear;
        SQL.Add('UPDATE Boxes SET');
        SQL.Add('Type = CASE WHEN :p0 = -1 THEN Type ELSE :p0 END,'); // Si iType = -1, on ne modifie pas le champ, sinon on lui donne la valeur iType
        SQL.Add('Weight = CASE WHEN :p1 = -1 THEN Weight ELSE :p1 END'); // Si iWeight = -1, on ne modifie pas le champ, sinon on lui donne la valeur iWeight
        SQL.Add('WHERE ID = :p2;');
        StartTransaction;
        Params[0].AsInteger := iType;
        Params[1].AsInteger := iWeight;
        for i1 := 0 to il.Count - 1 do begin  // il de type TGpIntegerList
          Params[2].AsInteger := il[i1];
          ExecSQL;
        end;
        Commit;
      end;
    end;
    Hélas ça ne marche pas, j'ai essayé différentes modifications mais rien n'est mis à jour dans ma BDD avec ce code.
    Du coup pour l'instant je passe par deux lots requêtes, ça marche mais ça me gêne de faire 2 requêtes pour ç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
    20
    21
    22
    23
      with qry do begin
        if iType > -1 then begin
          SQL.Clear;
          SQL.Add('UPDATE Boxes SET Type = :p0 WHERE ID = :p1;');
          StartTransaction;
          Params[0].AsInteger := iType;
          for i1 := 0 to il.Count - 1 do begin
            Params[1].AsInteger := il[i1];
            ExecSQL;
          end;
          Commit;
        end;
        if iWeight > -1 then begin
          SQL.Clear;
          SQL.Add('UPDATE Boxes SET Weight = :p0 WHERE ID = :p1;');
          StartTransaction;
          Params[0].AsInteger := iWeight;
          for i1 := 0 to il.Count - 1 do begin
            Params[1].AsInteger := il[i1];
            ExecSQL;
          end;
          Commit;
        end;
    Comment faire pour exécuter une seule requête, quel que soit le nombre de paramètres entrant en jeu, sans non plus passer par des tas de tests pour construire ma requête, genre "si param1 existe mais pas param2 alors SQL=...", "si param2 existe mais pas param1 alors SQL=...", "si param1 existe et param2 existe alors SQL=...", etc. ?
    Info: j'utilise SQLite.

  2. #2
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 254
    Par défaut
    peut-être avec ç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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    procedure TfrmMain.btnApplyPropertiesClick(Sender: TObject);
    var
      i1, iType, iWeight: Integer;
    	champs : string;
    begin
      ....
      with qry do begin
        champs := '';
    		if iType <> -1 then
    		  champs := 'Type = :p0';
    		if iWeight <> -1 then
    		begin
    		  if champs <> '' then 
    			  champs := champs + ', ';
    			champs := champs + 'Weight = :p1';
    		end;
     
    	  if champs <> ''
    		begin
    		  SQL.Clear;
          SQL.Add('UPDATE Boxes SET ');
          SQL.Add(champs);
          SQL.Add(' WHERE ID = :p2;');
          StartTransaction;
          Params[0].AsInteger := iType;
          Params[1].AsInteger := iWeight;
          for i1 := 0 to il.Count - 1 do begin  // il de type TGpIntegerList
            Params[2].AsInteger := il[i1];
            ExecSQL;
          end;
          Commit;
    		end;
      end;
    end;

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Non, ça ne marche pas; j'avais essayé une idée similaire, en utilisant un TStringList à la place de ta variable "champs" pour y ajouter les lignes SQL, et ce code pour ne pas avoir à gérer la virgule moi-même:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SQL.Add(sl.CommaText); // SQL.Add(champs);
    mais ensuite le nombre de Params ne correspond pas forcément: si il n'y a qu'un champs à mettre à jour, je me retrouve avec des "index out of bounds" pour les Params. J'ai aussi essayé en nommant les paramètres (puis Params.ParamByName('monparam').AsInteger pour les affectations...) mais ça ne passait pas non plus (je ne me souviens plus de l'erreur)...

  4. #4
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 254
    Par défaut
    Ah effectivement j'avais pas fait attention aux paramètres.

    Oui, il faudra passer par des paramètres nommés, comme ça tu n'aurais pas le problème de passer 3 paramètres alors que ta requete n'en utilise seulement 2

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    707
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 707
    Par défaut
    Je pense qu'il y a un bug dans le potage parce qu'en simplifiant avec une seule variable...

    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
    with qry do begin
      SQL.Add('UPDATE Boxes SET');
      SQL.Add('Type = CASE WHEN :p0 THEN :p0 ELSE Type END');
      SQL.Add('WHERE ID = :p1;');
      StartTransaction;
      if iType <> -1 then
        Params[0].AsInteger := iType
      else begin
        Params[0].Clear;
        Params[0].Bound := TRUE;
      end;
      for i1 := 0 to il.Count - 1 do begin
        Params[1].AsInteger := il[i1];
        ExecSQL;
      end;
      Commit;
    end;
    ...les champs sont mis à jour mais avec la valeur de :p1 au lieu de :p0 !!!

  6. #6
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 254
    Par défaut
    J'en reviens à mon code mais avec des paramètres nommés :
    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
    27
    	with qry do begin
    		champs := '';
    		if iType <> -1 then
    			champs := 'Type = :p0';
    		if iWeight <> -1 then
    		begin
    			if champs <> '' then 
    				champs := champs + ', ';
    			champs := champs + 'Weight = :p1';
    		end;
     
    		if champs <> ''
    		begin
    			SQL.Clear;
    			SQL.Add('UPDATE Boxes SET ');
    			SQL.Add(champs);
    			SQL.Add(' WHERE ID = :p2;');
    			StartTransaction;
    			Parameters.ParamByName('p0').Value := iType;
    			Parameters.ParamByName('p1').Value := iWeight;
    			for i1 := 0 to il.Count - 1 do begin  // il de type TGpIntegerList
    				Parameters.ParamByName('p2').Value := il[i1];
    				ExecSQL;
    			end;
    			Commit;
    		end;
    	end;

Discussions similaires

  1. [AC-2007] Requête paramétrée avec des conditions
    Par sami0701 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 19/05/2014, 20h28
  2. [PHP 5.3] Changement de valeur variable selon condition
    Par arthuro45 dans le forum Langage
    Réponses: 10
    Dernier message: 20/06/2010, 21h36
  3. Affichage variable selon conditions
    Par Kastor45 dans le forum LabVIEW
    Réponses: 1
    Dernier message: 11/04/2008, 00h07
  4. Requète paramétrée avec résultat variable
    Par slackjayo dans le forum Access
    Réponses: 2
    Dernier message: 28/04/2006, 20h39
  5. Requête, paramètre et variable
    Par Maludi dans le forum Access
    Réponses: 6
    Dernier message: 16/12/2005, 12h34

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