Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/08/2011, 00h45   #1
Invité régulier
 
Inscription : juillet 2009
Messages : 15
Détails du profil
Informations forums :
Inscription : juillet 2009
Messages : 15
Points : 7
Points : 7
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 :
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 :
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 :
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 :
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 :
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.
Barbrady est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/08/2011, 12h09   #2
Rédacteur/Modérateur
 
Avatar de fadace
 
Homme Fabien Celaia
Administrateur de base de données
Inscription : octobre 2002
Messages : 3 779
Détails du profil
Informations personnelles :
Nom : Homme Fabien Celaia
Âge : 41
Localisation : Suisse

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

Informations forums :
Inscription : octobre 2002
Messages : 3 779
Points : 8 124
Points : 8 124
Envoyer un message via ICQ à fadace Envoyer un message via Skype™ à fadace
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 / Sybase / MS-SQL / DB2 / Informix / Postgresql
Administrateur SAP
Mes articles

Attention : pas de réponse technique par MP : pensez aux autres, passez par les forums !
fadace est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h02.


 
 
 
 
Partenaires

Hébergement Web