[SQL SERVER] Comparaison de table [Presque resolu]

Comparaison de table [Presque resolu] [SQL SERVER] - SQL/NoSQL - Programmation

Marsh Posté le 15-07-2004 à 09:19:44    

Bonjour je vous explique mon probleme
 
je souhaite comparer deux tables aux champs identiques, et insérer dans une autre table les champs qui ont été modifiés avec la date de la comparaison, et le type de modification.
 
J'ai donc fait un couple insert / update pour chaque champs de mes tables, et ca marche. J'ai intégré cela dans un lot DTS.
 
Pour les nouvelles entrées (symétrique pour entrée supprimée)
 

Code :
  1. INSERT INTO HISTO (champs1..ChampsN)
  2. SELECT *
  3. FROM IMPORT
  4. WHERE IMPORT.champs1 NOT IN
  5.    (SELECT TRAVAIL.champs1 FROM TRAVAIL)
  6. UPDATE HISTO
  7. SET dateCourante=GETDATE(),commentaire='Nouvelle Entrée'
  8. WHERE dateCourante IS NULL


 
Pour les modifications
 

Code :
  1. INSERT INTO HISTO (champs1..ChampsN)
  2. SELECT I.champs1,..,I.champsN
  3. FROM IMPORT I, TRAVAIL T
  4. WHERE I.champs1=T.champs1 AND I.champs2!=T.champs2
  5. UPDATE HISTO
  6. SET dateCourante=GETDATE(),commentaire='Modification champs2'
  7. WHERE dateCourante IS NULL


 
Mais comme j'ai beaucoup de champs dans ces tables, je trouve fastidieux de devoir retaper N fois les même lignes, d'autant plus que si des champs changent il faut faire pleins de modifications.
 
je pense donc faire une boucle mais il me manque encore des notions
 

Code :
  1. DECLARE @champs nvarchar(30) #pour stocker le nom du champs
  2. DECLARE @numeroChamps numeric(9) #pour stocker le numéro du champs
  3. @numeroChamps=2 #je ne veux pas qu'on commence au premier champs car traitement particulier
  4. WHILE (il reste des champs)
  5. BEGIN
  6. INSERT INTO HISTO (champs1..ChampsN)
  7. SELECT I.champs1,..,I.champsN
  8. FROM IMPORT I, TRAVAIL T
  9. WHERE I.champs1=T.champs1 AND I.@champs!=T.@champs
  10. UPDATE HISTO
  11. SET dateCourante=GETDATE(),commentaire='Modification '+@champs
  12. WHERE dateCourante IS NULL
  13. @numeroChamps+=1
  14. END


 
merci d'avance si vous pouvez m'aidé


Message édité par rigo le 27-07-2004 à 13:11:33
Reply

Marsh Posté le 15-07-2004 à 09:19:44   

Reply

Marsh Posté le 17-07-2004 à 01:12:59    

à mon avis, "simplement" ce n'est pas possible
Quel est le volume de données à traiter ?
Pour un cas comme ça, mieux vaut écrire une proc et utiliser des curseurs, a priori


---------------
di. / www.diredaredare.org - Ailes de la ville
Reply

Marsh Posté le 19-07-2004 à 08:44:50    

tout d'abord merci pour votre reponse.
 
les tables a comparée font 32 champs et comportent environ 1700 entrée.
 
je serai interressé par un petit exemple de procedure avec curseur, pour ce cas precis.
 
merci d'avance

Reply

Marsh Posté le 19-07-2004 à 11:17:45    

voila un petit exemple en suposant que tu a une clef unique identique sur tes deux tables comme premiere column:

Code :
  1. DECLARE @tableid int,
  2. @table1 varchar(50),
  3. @table2 varchar(50),
  4. @column varchar(50),
  5. @sql varchar(4000),
  6. @index int,
  7. @keycolumn varchar(50)
  8. SELECT @table1 = '[OLD_TABLE'
  9. SELECT @table2 = '[NEW_TABLE]'
  10. SELECT @index = 0
  11. SELECT @tableid = [id] FROM sysobjects
  12. WHERE [name] = @table1 and xtype = 'u'
  13. DECLARE mycursor CURSOR FOR
  14. SELECT '[' + [name] + ']' FROM syscolumns WHERE [id] = @tableid
  15. ORDER BY colid
  16. OPEN mycursor
  17. FETCH NEXT FROM mycursor INTO @column
  18. WHILE (@@fetch_status <> -1)
  19. BEGIN
  20. IF (@@fetch_status <> -2)
  21. BEGIN
  22.  IF (@index = 0)
  23.  BEGIN
  24.   SELECT @index = @index + 1
  25.   SELECT @keycolumn = @column
  26.   SELECT @sql = 'SELECT getdate(), CASE WHEN T1.' + @column + ' IS NULL THEN ''NEW ROW'''
  27.   SELECT @sql = @sql + ' WHEN T2.' + @column + ' IS NULL THEN ''DELETED ROW'''
  28.   SELECT @sql = @sql + ' WHEN '
  29.  END
  30.  IF (@index > 1)
  31.  BEGIN
  32.   SELECT @sql = @sql + ' AND '
  33.  END
  34.  SELECT @index = @index + 1
  35.  SELECT @sql = @sql + 'T1.' + @column + ' = ' + 'T2.' + @column
  36. END
  37. FETCH NEXT FROM mycursor INTO @column
  38. END
  39. DEALLOCATE mycursor
  40. SELECT @sql = @sql + ' THEN ''NOT MODIFIED'''
  41. SELECT @sql = @sql + ' ELSE ''MODIFIED'' END AS STATUS, T1.*, T2.*'
  42. SELECT @sql = @sql + ' FROM ' + @table1 + ' AS T1 FULL JOIN ' + @table2 + ' AS T2 ON T1.' + @keycolumn + ' = T2.' + @keycolumn
  43. EXEC (@sql)

Reply

Marsh Posté le 19-07-2004 à 11:32:38    

Tu peux ensuite sauvegarder cette requete dans une procedure afin d'ameliorer les performances et automatiser la mise a jours de tes tables.

Reply

Marsh Posté le 19-07-2004 à 11:40:48    

ok merci beaucoup je rgarde ca attentivement

Reply

Marsh Posté le 26-07-2004 à 14:34:05    

Petit Up pour indiquer un petit changement de problématique [:arhendal]

Reply

Marsh Posté le 27-07-2004 à 13:15:08    

Bon j'essaie avec un curseur mais c'est pas encore ca...
 

Code :
  1. DECLARE @tableid int,
  2.    @table1 varchar(50),
  3.    @column varchar(50),
  4.    @index int,
  5.    @keycolumn varchar(50)
  6. SELECT @table1 = 'IMPORT'
  7. SELECT @index = 1
  8.  
  9.   SELECT @tableid = [id] FROM sysobjects
  10.    WHERE [name] = @table1 and xtype = 'u'
  11.  
  12.   DECLARE mycursor CURSOR FOR
  13.    SELECT '[' + [name] + ']' FROM syscolumns WHERE [id] = @tableid
  14.    ORDER BY colid
  15.  
  16.   OPEN mycursor
  17.  
  18.   FETCH NEXT FROM mycursor INTO @column
  19.  
  20.   WHILE (@@fetch_status <> -1)
  21.   BEGIN
  22.    IF (@@fetch_status <> -2)
  23.    BEGIN
  24.      IF (@index > 1)
  25.      BEGIN
  26. SELECT @index = @index + 1
  27. INSERT INTO HISTO (champs1..ChampsN)
  28. SELECT I.champs1,..,I.champsN
  29. FROM IMPORT I, TRAVAIL T
  30. WHERE I.champs1=T.champs1 AND 'I.'+@column!='T.'+@column
  31. UPDATE HISTOa
  32. SET dateCourante=GETDATE(),commentaire='Modification'+@column
  33. WHERE dateCourante IS NULL   
  34.      END
  35.    END
  36.    FETCH NEXT FROM mycursor INTO @column
  37.   END
  38.   DEALLOCATE mycursor

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed