Je dois surveiller les mises =E0 jour effectu=E9es sur une table pour y
d=E9tecter certains mouvement (cr=E9ation / suppression d'enregistrements
et mise =E0 jour d'une colonne).
Lorsque ces mouvements se produisent, je dois cr=E9er, dans un
r=E9pertoire, un fichier ".txt" (un pour chaque mouvement) contenant
certains champs de ces enregistrements.
Je pensais utiliser des triggers dans lesquels j'utiliserais un curseur
sur les tables INSERTED, DELETED et UPDATED pour analyser les
mouvements et cr=E9er le cas =E9ch=E9ant les fichiers textes via les
m=E9thodes de la classe "Scripting.FileSystemObject".
A noter qu'il n'y aura jamais de mise =E0 jour "massive" dans cette
table (tout au plus une dizaine de m.a.j par transaction).
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
SQLpro
Bonjour,
"Jean" a écrit :
Bonjour à tous(tes)
Je dois surveiller les mises à jour effectuées sur une table pour y détecter certains mouvement (création / suppression d'enregistrements et mise à jour d'une colonne). Lorsque ces mouvements se produisent, je dois créer, dans un répertoire, un fichier ".txt" (un pour chaque mouvement) contenant certains champs de ces enregistrements.
Je pensais utiliser des triggers dans lesquels j'utiliserais un curseur sur les tables INSERTED, DELETED et UPDATED pour analyser les mouvements et créer le cas échéant les fichiers textes via les méthodes de la classe "Scripting.FileSystemObject". A noter qu'il n'y aura jamais de mise à jour "massive" dans cette table (tout au plus une dizaine de m.a.j par transaction).
Cela vous semble t'il une solution "orthodoxe" ?
Faisable mais pas du tout "orthodoxe". Sachant qu'un trigger se déclenche AU SEIN DE LA TRANSACTION, vous allez obtenir des temps de transaction démesurés, générer de la contention au mieux, au pire des blocages et des interblocages. Votre application aura des performances lamentable en particulier lorsqu'il y aura plusieurs utilisateurs actifs. De plus l'utilisation massive du système de fichier de l'OS sur lequel est installé le serveur SQL, NUIT GRAVEMENT à ce dernier. Préférez dans ce cas implémenter une solution purement COBOL, c'est le langage ayant les meilleures performances en accès fichier...
Si néanmoins vous êtes à la recherche d'une solution intelligente et performante, pensez que ce qui est le plus apte à collecter des données lorsque vous avez une base de données relationelle comme SQL Server, c'est justement SQL Server lui même ! Ajoutez donc une table ou un ensemble de tables pour traquer les modifs et enregistrez les dedans. Croisez vos infos avec la table sysprocesses de la manière suivante :
-- la table des données CREATE TABLE T_APISTER_APT (CLEF INT NOT NULL PRIMARY KEY, DATA VARCHAR(32)) GO
-- la table traçant les modifs CREATE TABLE T_H_APISTER_APT -- même colonne que la table d(origine (CLEF INT NOT NULL, DATA VARCHAR(32), -- colonne spéciale d'historisation H_METHODE CHAR(1) CHECK (H_METHODE IN ('U', 'D')), -- U pour Update, D pour Delete H_HORODATAGE DATETIME, H_HOST_NAME NCHAR(128), H_PRGM_NAME NCHAR(128), H_NT_DOMAINE NCHAR(128), H_NT_USERNAME NCHAR(128), H_NET_ADDRESS NCHAR(12), H_LOGIN_NAME NCHAR(128) ) GO
-- le trigger de traçage CREATE TRIGGER E_UD_APT ON T_APISTER_APT FOR UPDATE, DELETE AS INSERT INTO T_H_APISTER_APT SELECT d.*, CASE WHEN EXISTS(SELECT * FROM inserted) THEN 'U' ELSE 'D' END , CURRENT_TIMESTAMP, hostname, program_name , nt_domain, nt_username, net_address, loginame FROM deleted AS d CROSS JOIN master.dbo.sysprocesses as p WHERE p.spid = @@SPID GO
-- test :
INSERT INTO T_APISTER_APT VALUES (1, 'toto') INSERT INTO T_APISTER_APT VALUES (2, 'titi')
UPDATE T_APISTER_APT SET DATA = 'tutu'
DELETE T_APISTER_APT WHERE CLEF = 1
SELECT * FROM T_H_APISTER_APT
CLEF DATA H_METHODE H_HORODATAGE H_HOST_NAME
H_PRGM_NAME H_NT_DOMAINE
H_NT_USERNAME
H_NET_ADDRESS H_LOGIN_NAME
----------- -------------------------------- --------- ------------------------------------------------------ -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- ------------- -------------------------------------------------------------------------------------------------------------------------------- 1 toto U 2006-07-18 17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
2 titi U 2006-07-18 17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
1 tutu D 2006-07-18 17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
A +
Merci d'avance
-- Frédéric BROUARD - MVP SQL Server, expert SGBDR & SQL Le site SQL et les SGBDR http://sqlpro.developpez.com Audit, conseil, formation, modélisation, optimisation => http://www.datasapiens.com
Bonjour,
"Jean" a écrit :
Bonjour à tous(tes)
Je dois surveiller les mises à jour effectuées sur une table pour y
détecter certains mouvement (création / suppression d'enregistrements
et mise à jour d'une colonne).
Lorsque ces mouvements se produisent, je dois créer, dans un
répertoire, un fichier ".txt" (un pour chaque mouvement) contenant
certains champs de ces enregistrements.
Je pensais utiliser des triggers dans lesquels j'utiliserais un curseur
sur les tables INSERTED, DELETED et UPDATED pour analyser les
mouvements et créer le cas échéant les fichiers textes via les
méthodes de la classe "Scripting.FileSystemObject".
A noter qu'il n'y aura jamais de mise à jour "massive" dans cette
table (tout au plus une dizaine de m.a.j par transaction).
Cela vous semble t'il une solution "orthodoxe" ?
Faisable mais pas du tout "orthodoxe". Sachant qu'un trigger se déclenche AU
SEIN DE LA TRANSACTION, vous allez obtenir des temps de transaction
démesurés, générer de la contention au mieux, au pire des blocages et des
interblocages.
Votre application aura des performances lamentable en particulier lorsqu'il
y aura plusieurs utilisateurs actifs.
De plus l'utilisation massive du système de fichier de l'OS sur lequel est
installé le serveur SQL, NUIT GRAVEMENT à ce dernier.
Préférez dans ce cas implémenter une solution purement COBOL, c'est le
langage ayant les meilleures performances en accès fichier...
Si néanmoins vous êtes à la recherche d'une solution intelligente et
performante, pensez que ce qui est le plus apte à collecter des données
lorsque vous avez une base de données relationelle comme SQL Server, c'est
justement SQL Server lui même ! Ajoutez donc une table ou un ensemble de
tables pour traquer les modifs et enregistrez les dedans. Croisez vos infos
avec la table sysprocesses de la manière suivante :
-- la table des données
CREATE TABLE T_APISTER_APT
(CLEF INT NOT NULL PRIMARY KEY,
DATA VARCHAR(32))
GO
-- la table traçant les modifs
CREATE TABLE T_H_APISTER_APT
-- même colonne que la table d(origine
(CLEF INT NOT NULL,
DATA VARCHAR(32),
-- colonne spéciale d'historisation
H_METHODE CHAR(1) CHECK (H_METHODE IN ('U', 'D')), -- U pour Update, D pour
Delete
H_HORODATAGE DATETIME,
H_HOST_NAME NCHAR(128),
H_PRGM_NAME NCHAR(128),
H_NT_DOMAINE NCHAR(128),
H_NT_USERNAME NCHAR(128),
H_NET_ADDRESS NCHAR(12),
H_LOGIN_NAME NCHAR(128)
)
GO
-- le trigger de traçage
CREATE TRIGGER E_UD_APT
ON T_APISTER_APT
FOR UPDATE, DELETE
AS
INSERT INTO T_H_APISTER_APT
SELECT d.*,
CASE
WHEN EXISTS(SELECT *
FROM inserted)
THEN 'U'
ELSE 'D'
END ,
CURRENT_TIMESTAMP,
hostname,
program_name ,
nt_domain,
nt_username,
net_address,
loginame
FROM deleted AS d
CROSS JOIN master.dbo.sysprocesses as p
WHERE p.spid = @@SPID
GO
-- test :
INSERT INTO T_APISTER_APT VALUES (1, 'toto')
INSERT INTO T_APISTER_APT VALUES (2, 'titi')
UPDATE T_APISTER_APT
SET DATA = 'tutu'
DELETE T_APISTER_APT
WHERE CLEF = 1
SELECT *
FROM T_H_APISTER_APT
CLEF DATA H_METHODE H_HORODATAGE
H_HOST_NAME
H_PRGM_NAME
H_NT_DOMAINE
H_NT_USERNAME
H_NET_ADDRESS H_LOGIN_NAME
----------- -------------------------------- ---------
------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
-------------
--------------------------------------------------------------------------------------------------------------------------------
1 toto U 2006-07-18
17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
2 titi U 2006-07-18
17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
1 tutu D 2006-07-18
17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
A +
Merci d'avance
--
Frédéric BROUARD - MVP SQL Server, expert SGBDR & SQL
Le site SQL et les SGBDR http://sqlpro.developpez.com
Audit, conseil, formation, modélisation, optimisation
=> http://www.datasapiens.com
Je dois surveiller les mises à jour effectuées sur une table pour y détecter certains mouvement (création / suppression d'enregistrements et mise à jour d'une colonne). Lorsque ces mouvements se produisent, je dois créer, dans un répertoire, un fichier ".txt" (un pour chaque mouvement) contenant certains champs de ces enregistrements.
Je pensais utiliser des triggers dans lesquels j'utiliserais un curseur sur les tables INSERTED, DELETED et UPDATED pour analyser les mouvements et créer le cas échéant les fichiers textes via les méthodes de la classe "Scripting.FileSystemObject". A noter qu'il n'y aura jamais de mise à jour "massive" dans cette table (tout au plus une dizaine de m.a.j par transaction).
Cela vous semble t'il une solution "orthodoxe" ?
Faisable mais pas du tout "orthodoxe". Sachant qu'un trigger se déclenche AU SEIN DE LA TRANSACTION, vous allez obtenir des temps de transaction démesurés, générer de la contention au mieux, au pire des blocages et des interblocages. Votre application aura des performances lamentable en particulier lorsqu'il y aura plusieurs utilisateurs actifs. De plus l'utilisation massive du système de fichier de l'OS sur lequel est installé le serveur SQL, NUIT GRAVEMENT à ce dernier. Préférez dans ce cas implémenter une solution purement COBOL, c'est le langage ayant les meilleures performances en accès fichier...
Si néanmoins vous êtes à la recherche d'une solution intelligente et performante, pensez que ce qui est le plus apte à collecter des données lorsque vous avez une base de données relationelle comme SQL Server, c'est justement SQL Server lui même ! Ajoutez donc une table ou un ensemble de tables pour traquer les modifs et enregistrez les dedans. Croisez vos infos avec la table sysprocesses de la manière suivante :
-- la table des données CREATE TABLE T_APISTER_APT (CLEF INT NOT NULL PRIMARY KEY, DATA VARCHAR(32)) GO
-- la table traçant les modifs CREATE TABLE T_H_APISTER_APT -- même colonne que la table d(origine (CLEF INT NOT NULL, DATA VARCHAR(32), -- colonne spéciale d'historisation H_METHODE CHAR(1) CHECK (H_METHODE IN ('U', 'D')), -- U pour Update, D pour Delete H_HORODATAGE DATETIME, H_HOST_NAME NCHAR(128), H_PRGM_NAME NCHAR(128), H_NT_DOMAINE NCHAR(128), H_NT_USERNAME NCHAR(128), H_NET_ADDRESS NCHAR(12), H_LOGIN_NAME NCHAR(128) ) GO
-- le trigger de traçage CREATE TRIGGER E_UD_APT ON T_APISTER_APT FOR UPDATE, DELETE AS INSERT INTO T_H_APISTER_APT SELECT d.*, CASE WHEN EXISTS(SELECT * FROM inserted) THEN 'U' ELSE 'D' END , CURRENT_TIMESTAMP, hostname, program_name , nt_domain, nt_username, net_address, loginame FROM deleted AS d CROSS JOIN master.dbo.sysprocesses as p WHERE p.spid = @@SPID GO
-- test :
INSERT INTO T_APISTER_APT VALUES (1, 'toto') INSERT INTO T_APISTER_APT VALUES (2, 'titi')
UPDATE T_APISTER_APT SET DATA = 'tutu'
DELETE T_APISTER_APT WHERE CLEF = 1
SELECT * FROM T_H_APISTER_APT
CLEF DATA H_METHODE H_HORODATAGE H_HOST_NAME
H_PRGM_NAME H_NT_DOMAINE
H_NT_USERNAME
H_NET_ADDRESS H_LOGIN_NAME
----------- -------------------------------- --------- ------------------------------------------------------ -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- ------------- -------------------------------------------------------------------------------------------------------------------------------- 1 toto U 2006-07-18 17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
2 titi U 2006-07-18 17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
1 tutu D 2006-07-18 17:24:42.297 PCL4DEV11
Analyseur de requêtes SQL
0013720874A9 sa
A +
Merci d'avance
-- Frédéric BROUARD - MVP SQL Server, expert SGBDR & SQL Le site SQL et les SGBDR http://sqlpro.developpez.com Audit, conseil, formation, modélisation, optimisation => http://www.datasapiens.com