1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| CREATE TABLE A
(
ID INT IDENTITY CONSTRAINT PK_A PRIMARY KEY,
Nom VARCHAR(20) NOT NULL,
Prenom VARCHAR(20) NOT NULL,
Age TINYINT NOT NULL CONSTRAINT DF_A_Age DEFAULT 0 CONSTRAINT CHK_A_Age CHECK(Age <= 100) ,
Adresse VARCHAR(100) NOT NULL
)
GO
INSERT INTO dbo.A VALUES ('Nom1', 'Prenom1', 10, '10 rue du Yaourt, 31000 Toulouse')
INSERT INTO dbo.A VALUES ('Nom2', 'Prenom2', 20, '20 rue du Yaourt, 31000 Toulouse')
INSERT INTO dbo.A VALUES ('Nom3', 'Prenom3', 30, '30 rue du Yaourt, 31000 Toulouse')
INSERT INTO dbo.A VALUES ('Nom4', 'Prenom4', 40, '40 rue du Yaourt, 31000 Toulouse')
INSERT INTO dbo.A VALUES ('Nom5', 'Prenom5', 50, '50 rue du Yaourt, 31000 Toulouse')
GO
SELECT *
INTO dbo.B
FROM dbo.A
GO
ALTER TABLE dbo.B
ADD CONSTRAINT PK_B PRIMARY KEY (ID),
CONSTRAINT DF_B_Age DEFAULT 0 FOR Age,
CONSTRAINT CHK_B_Age CHECK(Age <= 100)
GO
-- Vérifie qu'un nom de colonne qui sera stocké dans C est bien une des colonnes de la table A
CREATE FUNCTION Fn_EstColonneDansTable (@nomColonne SYSNAME)
RETURNS BIT
AS
BEGIN
DECLARE @estColonneDansTable BIT
SELECT @estColonneDansTable = 1
FROM sys.columns C
JOIN sys.tables T ON T.object_id = C.object_id
WHERE T.name = 'A'
AND C.name = @nomColonne
RETURN ISNULL(@estColonneDansTable, 0)
END
-- Table qui contient la liste des colonnes à vérifier
CREATE TABLE C
(
nomColonne SYSNAME CONSTRAINT CHK_C_nomColonne CHECK (dbo.Fn_EstColonneDansTable(nomColonne) = 1)
)
-- Colonnes à vérifier
INSERT INTO dbo.C VALUES ('nom')
INSERT INTO dbo.C VALUES ('prenom')
GO
-- Le trigger
ALTER TRIGGER TR_AU_B
ON dbo.B
AFTER UPDATE
AS
BEGIN
DECLARE @SQL NVARCHAR(256),
@listeColonnesPasAVerifier NVARCHAR(256),
@listeColonnesAVerifier NVARCHAR(256)
;WITH
CTE_LISTE_COLONNES (colonne) AS -- Recherche la liste des colonnes qu'il fautdra peut-être mettre à jour
(
SELECT C.name
FROM sys.columns C
JOIN sys.tables T ON C.object_id = T.object_id
WHERE T.name = 'A'
EXCEPT
-- Liste des colonnes déterminantes d'une différence
SELECT nomColonne
FROM dbo.C
EXCEPT
SELECT 'ID'
)
-- Conservation de la liste des colonnes devant être mises à jour, séparées par dés virgules
SELECT @listeColonnesPasAVerifier = ISNULL(@listeColonnesPasAVerifier, '') + colonne + ' = B.' + colonne + ', '
FROM CTE_LISTE_COLONNES
-- Suppression de la virgule finale
SELECT @listeColonnesPasAVerifier = LEFT(@listeColonnesPasAVerifier, LEN(@listeColonnesPasAVerifier) - 1)
-- Si la liste des colonnes est valuée (<=> il y a des colonnes à mettre à jour)
IF @listeColonnesPasAVerifier IS NOT NULL
BEGIN
-- Recherche de la liste des colonnes à vérifier
SELECT @listeColonnesAVerifier = ISNULL(@listeColonnesAVerifier, '') + 'B.' + nomColonne + ' <> A.' + nomColonne + ' AND '
FROM dbo.C
-- Suppression du AND final
SELECT @listeColonnesAVerifier = LEFT(@listeColonnesAVerifier, LEN(@listeColonnesAVerifier) - LEN(' AND '))
IF @listeColonnesAVerifier IS NOT NULL
BEGIN
SET @SQL = 'UPDATE maBD.dbo.A SET ' + @listeColonnesPasAVerifier +
' FROM maBD.dbo.B AS B JOIN maBD.dbo.A AS A ON A.ID = B.ID' +
' WHERE ' + @listeColonnesAVerifier
END
-- PRINT @SQL
EXEC master.dbo.sp_executeSQL @SQL
END
END
GO
-- Test
UPDATE dbo.B
SET Adresse = REPLACE(Adresse, 'Yaourt', 'Jambon')
GO
-- Vérification
SELECT * FROM dbo.A
SELECT * FROM dbo.B |
Partager