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

 

  1. #1
    Membre régulier
    Inscrit en
    avril 2010
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 114
    Points : 106
    Points
    106

    Par défaut Script excecute block pour faire un Update champs avec des valeurs consécutives, firebird 2.5

    Bonjour,
    Je voulais savoir es-qu’il y aurai moyen d’écrire un script (execute block )pour pouvoir affecter des valeurs à un champs (préalablement null ) des valeurs entière (1,2,3 ......)
    Au lieu de programmer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
             i:=0;
             matable.first;
             while not matable.eof do
                begin
                   i:=i+1;
                   matable.edit;
                   matable.monchamps.value:=i;
                   matable.post;
                   matable.next;  
                end;
    Merci;

  2. #2
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 9 345
    Points : 22 713
    Points
    22 713
    Billets dans le blog
    11

    Par défaut

    Bonjour,
    je vois plusieurs manières de faire selon si vous voulez garder ce traitement au cas où (CREATE PROCEDURE) ou s'il s'agit d'un usage unique (EXECUTE BLOCK)

    Dans les deux cas il faut quand même un identifiant unique pour votre table sinon il y a toujours la possibilité d'utiliser l'identifiant caché RDB$DB_KEY

    exemple soit une table TEST
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TABLE TEST
    (
      COL1 Varchar(5),
      A Smallint
    );
    remplie comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    INSERT INTO TEST(COL1) VALUES ('A');
    INSERT INTO TEST(COL1) VALUES ('Z');
    INSERT INTO TEST(COL1) VALUES ('R');
    INSERT INTO TEST(COL1) VALUES ('U');
    INSERT INTO TEST(COL1) VALUES ('I');
    INSERT INTO TEST(COL1) VALUES ('B');
    Le corps ressemble à ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    AS 
     DECLARE VARIABLE I INTEGER; -- incrément
     DECLARE VARIABLE K CHAR(8) CHARACTER SET OCTETS; -- clé magique 
    BEGIN 
     I=0;
     FOR SELECT RDB$DB_KEY FROM TEST ORDER BY COL1 INTO :K  -- à l'occasion un tri   
      DO BEGIN
              I=I+1;
              UPDATE TEST SET A=:I WHERE RDB$DB_KEY=:K;
           END
    END
    on obtient alors si l'on applique le tri
    A 1
    Z 6
    R 4
    U 5
    I 3
    B 2
    sinon on aura l'ordre d'insertion de lignes
    A 1
    Z 2
    R 3
    U 4
    I 5
    B 6
    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 (Berlin, Tokyo) 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
    Expert éminent

    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    3 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 3 760
    Points : 8 610
    Points
    8 610
    Billets dans le blog
    1

    Par défaut

    Les SGBDR sont beaucoup plus performants avec des requêtes ensemblistes, ils sont conçus pour ça

    Voici une solution bien plus simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    with tab1 (ltr) as                                    
        (select 'A'                
         union all                                        
         select 'B'                 
         union all                                        
         select 'C'             
         union all                                        
         select 'D'             
         union all                                        
         select 'E')              
    select ltr                                 
         , row_number() over (order by ltr)    
    from tab1                                  
    ;
    Résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    LTR                   £1 
    A                      1 
    B                      2 
    C                      3 
    D                      4 
    E                      5

  4. #4
    Membre régulier
    Inscrit en
    avril 2010
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 114
    Points : 106
    Points
    106

    Par défaut

    Super merci Sergio beaucoup ça marche.
    Je vais essayer la solution de escartefigue et je vous rendrais la réponse

  5. #5
    Membre régulier
    Inscrit en
    avril 2010
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 114
    Points : 106
    Points
    106

    Par défaut

    @escartefigue Désolé je n'ai su utiliser le script

  6. #6
    Expert éminent

    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    3 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 3 760
    Points : 8 610
    Points
    8 610
    Billets dans le blog
    1

    Par défaut

    La première partie ne m'a servi que pour créer le jeu d'essai (plutôt que de créer une table), il faut utiliser uniquement la requête SELECT pour générer le ROW_NUMBER

  7. #7
    Membre régulier
    Inscrit en
    avril 2010
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 114
    Points : 106
    Points
    106

    Par défaut

    Citation Envoyé par escartefigue Voir le message
    La première partie ne m'a servi que pour créer le jeu d'essai (plutôt que de créer une table), il faut utiliser uniquement la requête SELECT pour générer le ROW_NUMBER
    En exécutant le script dans IBexpert , j'ai l'erreur function unknown ROW_NUMBER !!!!

  8. #8
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 9 345
    Points : 22 713
    Points
    22 713
    Billets dans le blog
    11

    Par défaut

    Bonsoir,

    Il me semble que les fonctions de fenêtrage c'est à partir de Firebird 3, ce qui m'a fait opter pour le bloc code puisqu'il s'agit de Firebird 2.5
    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 (Berlin, Tokyo) 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

  9. #9
    Expert éminent

    Homme Profil pro
    bourreau
    Inscrit en
    mars 2010
    Messages
    3 760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : mars 2010
    Messages : 3 760
    Points : 8 610
    Points
    8 610
    Billets dans le blog
    1

    Par défaut

    Ah bigre ! je n'avais pas prêté attention à la version !

  10. #10
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 9 345
    Points : 22 713
    Points
    22 713
    Billets dans le blog
    11

    Par défaut

    Je pense toutefois que l'on peut tenter d'autres solutions
    J'ai juste voulu, rapidement, proposer la solution la plus simple.

    par exemple, on peut obtenir le numéro de ligne de cette manière
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT
    rdb$db_key as k,col1,
    rdb$get_context('USER_TRANSACTION', 'row#') as row_number,
    rdb$set_context('USER_TRANSACTION', 'row#',
    coalesce(cast(rdb$get_context('USER_TRANSACTION', 'row#') as integer), 0) + 1)
    FROM Test a
    Faire un UPDATE (puisque c'est la question) à partir de là à part toujours dans un corps de procédure ou de bloc c'est le même principe puisqu'il faudra toujours en passer par 2 variables, le gain n'est pas exceptionnel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    AS 
     DECLARE VARIABLE I INTEGER;
     DECLARE VARIABLE X INTEGER;
     DECLARE VARIABLE K CHAR(8) CHARACTER SET OCTETS; -- clé magique 
    BEGIN 
     
     FOR SELECTrdb$db_key,
                       rdb$get_context('USER_TRANSACTION', 'r'),
                       rdb$set_context('USER_TRANSACTION', 'r', coalesce(cast(rdb$get_context('USER_TRANSACTION', 'r') as integer), 0) + 1) -- incrémentation 
              FROM Test order by col1 INTO :K,:I,:X 
      DO  UPDATE TEST SET A=:I WHERE RDB$DB_KEY=:K;
    END
    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 (Berlin, Tokyo) 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

  11. #11
    Membre régulier
    Inscrit en
    avril 2010
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 114
    Points : 106
    Points
    106

    Par défaut

    Bonjour,
    Merci Sergio pour la 2ème solution que j'ai tester Seulement elle saute le premier enregistrement
    C'est à dire le premier est à null puis les suivants 1,2,3......

  12. #12
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : janvier 2007
    Messages : 9 345
    Points : 22 713
    Points
    22 713
    Billets dans le blog
    11

    Par défaut

    je n'avais pas fait attention et juste tester le SELECT
    effectivement la variable de contexte n'est pas initialisée la première fois
    SOLUTION 1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    AS
     DECLARE VARIABLE I INTEGER;
     DECLARE VARIABLE X INTEGER;
     DECLARE VARIABLE K CHAR(8) CHARACTER SET OCTETS; -- clé magique 
    BEGIN
    SELECT rdb$set_context('USER_TRANSACTION', 'row#',0) FROM RDB$DATABASE INTO :I;
    FOR
    SELECT
    rdb$db_key as k,
    rdb$get_context('USER_TRANSACTION', 'row#') as row_number,
    rdb$set_context('USER_TRANSACTION', 'row#',
    cast(rdb$get_context('USER_TRANSACTION', 'row#') as integer) + 1)
    FROM Test a INTO :K,:I,:X
    DO UPDATE TEST SET A=:I WHERE RDB$DB_KEY=:K;
    ce qui revient à la même chose que j'avais proposé à mon premier post, donc l'utilisation de la variable de contexte est inutile

    SOLUTION 2
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    AS
     DECLARE VARIABLE I INTEGER;
     DECLARE VARIABLE X INTEGER;
     DECLARE VARIABLE K CHAR(8) CHARACTER SET OCTETS; -- clé magique 
    BEGIN
    FOR
    SELECT
    rdb$db_key as k,
    rdb$get_context('USER_TRANSACTION', 'row#') as row_number,
    rdb$set_context('USER_TRANSACTION', 'row#',
    COALESCE(CAST(rdb$get_context('USER_TRANSACTION', 'row#') as integer),0) + 1)
    FROM Test a INTO :K,:I,:X
    DO UPDATE TEST SET A=COALESCE(:I,0) WHERE RDB$DB_KEY=:K;
    END !
    NB : bien sûr on peut remplacer les 0 des deux coalesce par une autre valeur
    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 (Berlin, Tokyo) 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

  13. #13
    Membre régulier
    Inscrit en
    avril 2010
    Messages
    114
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 114
    Points : 106
    Points
    106

    Par défaut

    Merci Sergio

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

Discussions similaires

  1. SELECT sur le même champ avec des valeurs différentes
    Par SlimEmShady dans le forum Requêtes
    Réponses: 2
    Dernier message: 10/08/2017, 16h05
  2. Update champs avec des donnée d'autre champs.
    Par guigui69 dans le forum Langage SQL
    Réponses: 1
    Dernier message: 29/12/2009, 08h25
  3. Concaténer plusieurs champs avec des valeurs uniques
    Par stefposs dans le forum VBA Access
    Réponses: 10
    Dernier message: 30/05/2007, 17h42
  4. [JS] contrôle sur la saisie d'un champ avec des valeurs numeriques ?
    Par adil_vpb dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 22/03/2007, 11h12
  5. problème pour faire un update
    Par ph_anrys dans le forum PHP & MySQL
    Réponses: 9
    Dernier message: 16/03/2006, 15h48

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