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

Développement SQL Server Discussion :

Dupliquer des enregistrements quand IDENTITY


Sujet :

Développement SQL Server

  1. #1
    Membre à l'essai
    Inscrit en
    Juillet 2009
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 15
    Points : 11
    Points
    11
    Par défaut Dupliquer des enregistrements quand IDENTITY
    Bonjour,

    J'ai crée dans mon entreprise un Workflow pour la création, modification et suppression de produit de l'usine.
    Quand une fiche article est clôturée celle-ci va mettre automatiquement à jour des tables d'une autre BDD (JOB SQL tournant tous les jours la nuit).

    A savoir que la BDD pour le Workflow et celui permettant de stocker les données articles sont sur le même serveur SQL Server 2005.

    Mon application et mes PS avec mes JOB SQL fonctionnent très bien, mais voilà je dois apporter une modification à mon JOB de mise à jour automatique des données articles afin qu'il soit plus souple.
    Si j'ai une modification article je dois historiser les données article avant ma mise à jour automatique. Puis mettre à jour les informations de l'article modifié.

    Actuellement, je duplique avec des requêtes SQL du genre =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    INSERT INTO BDDArticle.dbo.maTable(cln_01, cln_02, date_suppression, ...)
    SELECT cln_01, cln_02, CURRENT_TIMESTAMP, ...
    FROM BDDArticle.dbo.maTable 
    WHERE id_article = yyyy;
    A cette étape je en sélectionne pas ma colonne auto-incrémentée (Identity) et j'ajoute dans mon SELECT pour la date de suppression un "CURRENT_TIMESTAMP".
    En gros les historiques ont un ID plus fort dans la table que les données de l'article en vigueur.
    Si j'aurais mis une date de suppression pour l'article modifié et ensuite ajouté les nouvelles données j'aurais eu un ID différent et cela aurait posé problème pour d'autres applications pour le service Qualité, Production, Magasin, ... Au niveau des paramètres et des stats.

    Je ne sais pas si j'ai bien été clair sur ce point particulier ?


    Ensuite j'exécute une requête SQL me permettant de mettre à jour l'article (celui avec l'ID le plus faible de la table).


    Ma question, c'est que je sélectionne les colonnes par leur nom en omettant l'ID de l'occurrence car Identity et je rentre manuellement la date de suppression.
    Seulement il se trouve que certaines tables servant de destination utilisé par mon Workflow peuvent-être modifiée sur leur structure. Le problème c'est que je dois absolument historiser la ligne entière en cas de modification article.
    L'idéal serait de faire =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    INSERT INTO BDDArticle.dbo.maTable 
    SELECT * 
    FROM BDDArticle.dbo.maTable 
    WHERE id_article = yyyy;
    Mais voilà la contrainte sur la colonne qui a Identity n'apprécie pas bien ce genre de chose. De plus, je ne peux pas renseigner manuellement la date de suppression.

    L'idée que j'ai commencé à faire est de créer une table temporaire =>
    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
     
    SELECT * 
    INTO #tmp 
    FROM BDDArticle.dbo.maTable 
    WHERE id_article = yyyy;
     
    UPDATE #tmp 
    SET date_suppression = CURRENT_TIMESTAMP;
     
    ALTER TABLE #tmp 
    DROP COLUMN id;
     
    INSERT INTO BDDArticle.dbo.maTable(cln_02, cln_03, cln_04, ...) 
    SELECT * 
    FROM BDDArticle.dbo.maTable;
    Mais voilà je dois préciser dans l'instruction "INSERT INTO" les noms des colonnes de destination.

    J'ai imaginé un cas comme celui-là après mon "DROP COLUMN" =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    INSERT INTO BDDArticle.dbo.maTable 
    SELECT Identity(), * 
    FROM BDDArticle.dbo.maTable;
    J'ai pas eu le temps de tester avant de partir, car j'ai cherché sur le net et sur les articles de ce site et j'ai pas trouvé une situation similaire à la mienne.

    L'une des soluce que je vois est d'utiliser les requêtes dynamiques. Je récupère toutes les colonnes de "BDDArticle.dbo.maTable" en excluant celle de "ID" dans le "WHERE" de la vue système. Ensuite =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    DECLARE @colonnes NVARCHAR(1000)
    DECLARE @var NVARCHAR(1000)
     
    --
    -- Traitement pour parcourir colonnes de la "BDDArticle.dbo.maTable" et de concaténer les résultats dans "@colonnes"
    --
     
    SET @var = 'INSERT INTO BDDArticle.dbo.maTable(' + @colonnes + ') 
    SELECT * 
    FROM BDDArticle.dbo.maTable;'
     
    exec sp_execute(@var);
    Sinon l'autre idée et de désactiver temporairement l'Identity puis de le réactiver en générant mes ID entre-temps, mais bon je trouve ça cra cra perso.


    Auriez-vous d'autres propositions ou des avis ?


    Merci d'avance pour votre aide.

  2. #2
    Rédacteur/Modérateur

    Avatar de Fabien Celaia
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2002
    Messages
    4 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Service public

    Informations forums :
    Inscription : Octobre 2002
    Messages : 4 220
    Points : 19 549
    Points
    19 549
    Billets dans le blog
    25
    Par défaut
    Vous n'avez pas tellement d'alternative, si vous insérez un champ comprenant un IDENTITY,

    • soit vous spécififiez vous-même le no, en étant passé avant cela en identity_insert


    • soit vous laissez faire l'identitdy, mais vous devez spécifier toutes vos colonnes (hormis celle de l'identity)

    La 2e méthode est la plus propre. De toute façon, en développement, il faut toujours nommer ses colonnes... ça évite bien des surprises,,,, surtout dans un SGBDR qui laisse insérer des colonnes entre les colonnes existantes...
    Sr DBA Oracle / MS-SQL / MySQL / Postgresql / SAP-Sybase / Informix / DB2

    N'oublie pas de consulter mes articles, mon blog, les cours et les FAQ SGBD

    Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums !

Discussions similaires

  1. [AC-2007] Dupliquer des enregistrements selon la valeur d'un champ
    Par youssefbsf dans le forum VBA Access
    Réponses: 3
    Dernier message: 18/08/2011, 15h27
  2. [XL-2002] Dupliquer des enregistrements
    Par eurekgeez dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 13/07/2011, 18h29
  3. [AC-2010] Dupliquer des enregistrements
    Par Vince26exe dans le forum VBA Access
    Réponses: 3
    Dernier message: 04/04/2011, 20h03
  4. Dupliquer des enregistrements
    Par yamino dans le forum SQL
    Réponses: 2
    Dernier message: 15/10/2008, 16h28
  5. dupliquer des enregistrements dans une nouvelle table
    Par CINQ_MARSIENNE dans le forum Modélisation
    Réponses: 3
    Dernier message: 15/09/2007, 01h31

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