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

SQL Firebird Discussion :

Création champ Primary Key dans table existante


Sujet :

SQL Firebird

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 46
    Points : 37
    Points
    37
    Par défaut Création champ Primary Key dans table existante
    Bonsoir,

    J'ai trouvé aujourd'hui une petite astuce bien utile que je vous livre ici.
    Le problème était le suivant :

    J'avais une table LZHISTOPRIXART contenant plusieurs milliers d'enregistrements, mais dans laquelle je n'avais pas de clé primaire. J'ai donc décidé d'ajouter un champ ID_LIGNE qui allait remplir cette fonction.

    Malheureusement c'était impossible car après la création de mon champ, toutes les lignes avaient l'ID 1 !!! (et pas null car j'avais créé un champ NON NULL). Je devais donc trouver un moyen de remplir ce champ avec les valeurs 1, 2, 3, 4, ... pour tous les enregistrements de la table.

    Je comptais faire une boucle dans laquelle j'aurais fait ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE lzhistoprixart SET id_ligne = ... WHERE ... ;
    Seulement voilà, que mettre comme clause dans le WHERE ??? N'ayant pas de clé primaire, et certaines valeurs apparaissant en double, je n'avais aucun moyen d'identifier chaque enregistrement de manière unique.

    C'est alors que j'ai repensé aux Curseurs. Je me suis documenté et j'ai finalement écrit cette procédure :

    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
    SET TERM ^ ;
     
    CREATE OR ALTER PROCEDURE renum
    AS
      DECLARE VARIABLE a INTEGER;
      DECLARE VARIABLE new_id INTEGER;
    BEGIN
      new_id = 1;
      FOR SELECT id_ligne FROM lzhistoprixart INTO :a AS CURSOR liste DO
      BEGIN
        UPDATE lzhistoprixart SET id_ligne = :new_id WHERE CURRENT OF liste;
        new_id = new_id + 1;
      END
    END^
     
    SET TERM ; ^
    La partie importante commence dans la boucle FOR SELECT dans laquelle je déclare que le résultat de mon select sera parcouru par un curseur appelé "liste". Le seul point obscur est l'utilisation de INTO :a qui me semble ne servir à rien (mais qui est cependant nécessaire...). Donc la première partie se résume à FOR SELECT ... AS CURSOR NomCurseur DO BEGIN ... END

    Ensuite, l'autre partie importante se trouve dans l'UPDATE, pour lequel le seul critère de la clause WHERE est CURRENT OF NomCurseur. Ainsi, le résultat de mon select est parcouru par le curseur "liste" que j'utilise à chaque exécution de l'update, afin de modifier uniquement l'enregistrement en cours.

    Victoire ça fonctionne, j'ai les valeurs 1, 2, 3, 4, 5, ... jusqu'à la fin de ma table

  2. #2
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut

    pourquoi se compliquer la vie quand on peut faire simple :

    1/ créer un générateur (G1 dans ce qui suit)
    2/ faire un update :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE lzhistoprixart SET id_ligne=(SELECT GEN_ID(G1,1) FROM RDB$DATABASE);
    mais c'est un bon exercice d'avoir travaillé avec les curseurs
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2002
    Messages : 46
    Points : 37
    Points
    37
    Par défaut

    C'est dingue, ça !!!
    Comment n'y ai-je pas pensé ?

    J'ai testé avec une grosse table de 100.000 lignes générées par FlameRobin pour voir laquelle des deux méthodes est la plus rapide, le résultat est pratiquement identique (2 à 3 secondes chacune). Donc elles sont équivalentes.

    Enfin, comme tu dis, ça m'aura au moins permis de faire connaissance avec les CURSEURS et je sens que ça va bien me servir dans un futur proche

    Bonne journée.

Discussions similaires

  1. Création d'une colonne dans table existante
    Par nawal59 dans le forum SQL
    Réponses: 2
    Dernier message: 26/01/2011, 10h09
  2. création nouvelle variable dans table existante
    Par meuah dans le forum Requêtes et SQL.
    Réponses: 0
    Dernier message: 16/05/2008, 10h00
  3. AutoIncrement Primary Key dans Make Table
    Par Jah78 dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 03/08/2007, 14h20
  4. ajouter primary key dans une table
    Par DJERDJAR YACINE dans le forum Langage SQL
    Réponses: 2
    Dernier message: 04/07/2007, 00h35
  5. table avec deux champs primary key
    Par gilles69 dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 20/03/2007, 11h44

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