Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Pb de test avec les tables Inserted et Deleted

4 réponses
Avatar
Jerome
Bonjour à tous,

j'ai un pb avec un If où je souhaite comparer des données d'entrée dans un
formulaire et les données de sorties pour déclencher une mise à jour des
champs via une procédure stockée.
Dans un trigger (ci-dessous) je place dans des variables les données issues
des tables Inserted et Deleted pour ensuite les comparer. Et là, le test IF
ne fonctionne pas, je ne passe pas le IF bien que j'ai des valeurs de champs
qui ont changées
Si quelqu'un pouvait m'éclairer sur ce pb. Est ce un pb dans l'utilisation
des tables Inserted - deleted ? L'erreur se trouve-t-elle dans ce code ou
dois je chercher ailleurs ?

-------------------------------------------------------------------
CREATE TRIGGER convert_clarion_sql_diffusion ON [dbo].[DFIC_DIFFUSION]
FOR INSERT, UPDATE
AS
declare @DateAncienne1 int
declare @DateAncienne2 int
declare @DateAConvertir1 int
declare @DateAConvertir2 int
declare @DateSQLConvertie1 datetime
declare @DateSQLConvertie2 datetime

set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
set @DateAConvertir2 = (select DDIF_DATE_EMISS from inserted)

set @DateAncienne1 = (select DDIF_DTE_DIFFUSIO from deleted)
set @DateAncienne2 = (select DDIF_DATE_EMISS from deleted)


if ((@DateAConvertir1 <> @DateAncienne1) OR (@DateAConvertir2 <>
@DateAncienne2) )
begin
execute DateClarionSQL @DateAConvertir1, @DateSQL = @DateSQLConvertie1
output
execute DateClarionSQL @DateAConvertir2, @DateSQL = @DateSQLConvertie2
output
...
--------------------------------------------------------------------------------------

Merci pour votre aide

Jerome

4 réponses

Avatar
Fred BROUARD
Un trigger ne s'exécute qu'UNE SEULE FOIS quelque soit le nombre de lignes
impacté par l'ordre.

Autrement dit, si l'ordre SQL suivant :
DELETE FROM MaTable
supprime 3 millions de lignes, alors le trigger FOR DELETE ne sera déclenché
qu'une seule fois et non pas trois millions de fois (et heureusement !).

Donc, dès que je voit une variable locale dans un trigger => le mec qui a écrit
ce code n'a rien compris aux triggers !

Le code d'un trigger doit être ensembliste => pas de variable locale, sauf dans
une boucle de curseur.

De plus comparer colonne à colonne va faire exploser le cout du trigger et les
performances seront lamentables à bloquante !!!
Imagine que pour faire une révison sur une voiture le mécanicien s'y prenne de
cette manière :
1) rentrer dans le garage la voiture qui se trouve dans le parking
2) mettre la voiture sur le pont
3) élever le pont
4) mesurer la pression du pneu avant droit
5) baisser le pont
6) retirer le voiture du pont
7) garer la voiture dans le parking
8) rentrer dans le garage la voiture qui se trouve dans le parking
9) mettre la voiture sur le pont
10) élever le pont
11 mesurer la pression du pneu avant gauche
12) baisser le pont
13) retirer le voiture du pont
14) garer la voiture dans le parking
...

de plus pour connaître les colonnes qui ont changées il suffit d'une seule
fonctions, COLUMNS_UPDATED() dont le fonctionnement est décrit ici :
http://sqlpro.developpez.com/cours/sqlserver/transactsql/#L5.3.2
elle nécessite un masque binaire.

Enfin, l'affectation de différentes variables se fait d'un bloc et non comme tu
le veut... ça c'est casse gueule :
set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
car s'il y a plusieurs lignes cela plante !

EN CONCLUSION :
que veut tu faire d'un point de vu fonctionnel ? De l'archivage ?? De la
traçabilité ???

A +


--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste Delphi, web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************

Jerome a écrit:
Bonjour à tous,

j'ai un pb avec un If où je souhaite comparer des données d'entrée dans un
formulaire et les données de sorties pour déclencher une mise à jour des
champs via une procédure stockée.
Dans un trigger (ci-dessous) je place dans des variables les données issues
des tables Inserted et Deleted pour ensuite les comparer. Et là, le test IF
ne fonctionne pas, je ne passe pas le IF bien que j'ai des valeurs de champs
qui ont changées
Si quelqu'un pouvait m'éclairer sur ce pb. Est ce un pb dans l'utilisation
des tables Inserted - deleted ? L'erreur se trouve-t-elle dans ce code ou
dois je chercher ailleurs ?

-------------------------------------------------------------------
CREATE TRIGGER convert_clarion_sql_diffusion ON [dbo].[DFIC_DIFFUSION]
FOR INSERT, UPDATE
AS
declare @DateAncienne1 int
declare @DateAncienne2 int
declare @DateAConvertir1 int
declare @DateAConvertir2 int
declare @DateSQLConvertie1 datetime
declare @DateSQLConvertie2 datetime

set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
set @DateAConvertir2 = (select DDIF_DATE_EMISS from inserted)

set @DateAncienne1 = (select DDIF_DTE_DIFFUSIO from deleted)
set @DateAncienne2 = (select DDIF_DATE_EMISS from deleted)


if ((@DateAConvertir1 <> @DateAncienne1) OR (@DateAConvertir2 <>
@DateAncienne2) )
begin
execute DateClarionSQL @DateAConvertir1, @DateSQL = @DateSQLConvertie1
output
execute DateClarionSQL @DateAConvertir2, @DateSQL = @DateSQLConvertie2
output
...
--------------------------------------------------------------------------------------

Merci pour votre aide

Jerome




Avatar
Jerome
Merci pour ta réponse

D'un point de vue fonctionnel, j'ai une application Windows et une PHP qui
communique sur la même base MSSQL. Pour des raisons spécifiques, l'appli
Windows utilise des dates en format Numérique (du type 74400 par exemple) et
l'appli PHP des dates au format datetime.
Aussi, quand l'appli Windows renseigne un masque de saisie et valide donc un
enregistrement (en création ou modif), je souhaitais mettre à jour la date
pour la version PHP et vice et versa.

Au début, l'appli PHP était en consultation simple et ce principe
fonctionnait dan sle sens de la mise à jour des dates de la version Windows
vers les dates format Datetime
Maintenant l'appli PHP peut modifier les données, je vouslais donc tester
dans ce trigger d'où venait la modif afin de déclencher la mise à jour des
dates Windows ou des dates Datetime, d'où ce test sur les tables Inserted et
Deleted. Dans mon cas de figure, je n'ai qu'un seul enregistrement pris en
compte à chaque fois.

Jerome


"Fred BROUARD" a écrit dans le message de news:

Un trigger ne s'exécute qu'UNE SEULE FOIS quelque soit le nombre de lignes
impacté par l'ordre.

Autrement dit, si l'ordre SQL suivant :
DELETE FROM MaTable
supprime 3 millions de lignes, alors le trigger FOR DELETE ne sera
déclenché qu'une seule fois et non pas trois millions de fois (et
heureusement !).

Donc, dès que je voit une variable locale dans un trigger => le mec qui a
écrit ce code n'a rien compris aux triggers !

Le code d'un trigger doit être ensembliste => pas de variable locale, sauf
dans une boucle de curseur.

De plus comparer colonne à colonne va faire exploser le cout du trigger et
les performances seront lamentables à bloquante !!!
Imagine que pour faire une révison sur une voiture le mécanicien s'y
prenne de cette manière :
1) rentrer dans le garage la voiture qui se trouve dans le parking
2) mettre la voiture sur le pont
3) élever le pont
4) mesurer la pression du pneu avant droit
5) baisser le pont
6) retirer le voiture du pont
7) garer la voiture dans le parking
8) rentrer dans le garage la voiture qui se trouve dans le parking
9) mettre la voiture sur le pont
10) élever le pont
11 mesurer la pression du pneu avant gauche
12) baisser le pont
13) retirer le voiture du pont
14) garer la voiture dans le parking
...

de plus pour connaître les colonnes qui ont changées il suffit d'une seule
fonctions, COLUMNS_UPDATED() dont le fonctionnement est décrit ici :
http://sqlpro.developpez.com/cours/sqlserver/transactsql/#L5.3.2
elle nécessite un masque binaire.

Enfin, l'affectation de différentes variables se fait d'un bloc et non
comme tu le veut... ça c'est casse gueule :
set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
car s'il y a plusieurs lignes cela plante !

EN CONCLUSION :
que veut tu faire d'un point de vu fonctionnel ? De l'archivage ?? De la
traçabilité ???

A +


--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste Delphi, web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************

Jerome a écrit:
Bonjour à tous,

j'ai un pb avec un If où je souhaite comparer des données d'entrée dans
un formulaire et les données de sorties pour déclencher une mise à jour
des champs via une procédure stockée.
Dans un trigger (ci-dessous) je place dans des variables les données
issues des tables Inserted et Deleted pour ensuite les comparer. Et là,
le test IF ne fonctionne pas, je ne passe pas le IF bien que j'ai des
valeurs de champs qui ont changées
Si quelqu'un pouvait m'éclairer sur ce pb. Est ce un pb dans
l'utilisation des tables Inserted - deleted ? L'erreur se trouve-t-elle
dans ce code ou dois je chercher ailleurs ?

-------------------------------------------------------------------
CREATE TRIGGER convert_clarion_sql_diffusion ON [dbo].[DFIC_DIFFUSION]
FOR INSERT, UPDATE
AS
declare @DateAncienne1 int
declare @DateAncienne2 int
declare @DateAConvertir1 int
declare @DateAConvertir2 int
declare @DateSQLConvertie1 datetime
declare @DateSQLConvertie2 datetime

set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
set @DateAConvertir2 = (select DDIF_DATE_EMISS from inserted)

set @DateAncienne1 = (select DDIF_DTE_DIFFUSIO from deleted)
set @DateAncienne2 = (select DDIF_DATE_EMISS from deleted)


if ((@DateAConvertir1 <> @DateAncienne1) OR (@DateAConvertir2 <>
@DateAncienne2) )
begin
execute DateClarionSQL @DateAConvertir1, @DateSQL = @DateSQLConvertie1
output
execute DateClarionSQL @DateAConvertir2, @DateSQL = @DateSQLConvertie2
output
...
--------------------------------------------------------------------------------------

Merci pour votre aide

Jerome





Avatar
Fred BROUARD
Le simple usage d'une UDF intégrée à la requête SQL d'insertion et celle de
modif devrait suffire. D'autant qu'en fait une date est un réel donc un :
SELECT CAST(38400 AS DATETIME) =>

------------------------------------------------------
2005-02-19 00:00:00.000
est largement suffisant et ultra performant !


Autrement dit dans ta requête d'insertion tu peut faire :

INSERT INTO MaTable (...)
VALUES ( ... CAST( @MaDatePHP - 21261 AS DATETIME), ... )


A toi de trouver le bon réglage pour 21261 (valeur que j'ai choisit arbitrairement !

A +



--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste Delphi, web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************

Jerome a écrit:
Merci pour ta réponse

D'un point de vue fonctionnel, j'ai une application Windows et une PHP qui
communique sur la même base MSSQL. Pour des raisons spécifiques, l'appli
Windows utilise des dates en format Numérique (du type 74400 par exemple) et
l'appli PHP des dates au format datetime.
Aussi, quand l'appli Windows renseigne un masque de saisie et valide donc un
enregistrement (en création ou modif), je souhaitais mettre à jour la date
pour la version PHP et vice et versa.

Au début, l'appli PHP était en consultation simple et ce principe
fonctionnait dan sle sens de la mise à jour des dates de la version Windows
vers les dates format Datetime
Maintenant l'appli PHP peut modifier les données, je vouslais donc tester
dans ce trigger d'où venait la modif afin de déclencher la mise à jour des
dates Windows ou des dates Datetime, d'où ce test sur les tables Inserted et
Deleted. Dans mon cas de figure, je n'ai qu'un seul enregistrement pris en
compte à chaque fois.

Jerome


"Fred BROUARD" a écrit dans le message de news:


Un trigger ne s'exécute qu'UNE SEULE FOIS quelque soit le nombre de lignes
impacté par l'ordre.

Autrement dit, si l'ordre SQL suivant :
DELETE FROM MaTable
supprime 3 millions de lignes, alors le trigger FOR DELETE ne sera
déclenché qu'une seule fois et non pas trois millions de fois (et
heureusement !).

Donc, dès que je voit une variable locale dans un trigger => le mec qui a
écrit ce code n'a rien compris aux triggers !

Le code d'un trigger doit être ensembliste => pas de variable locale, sauf
dans une boucle de curseur.

De plus comparer colonne à colonne va faire exploser le cout du trigger et
les performances seront lamentables à bloquante !!!
Imagine que pour faire une révison sur une voiture le mécanicien s'y
prenne de cette manière :
1) rentrer dans le garage la voiture qui se trouve dans le parking
2) mettre la voiture sur le pont
3) élever le pont
4) mesurer la pression du pneu avant droit
5) baisser le pont
6) retirer le voiture du pont
7) garer la voiture dans le parking
8) rentrer dans le garage la voiture qui se trouve dans le parking
9) mettre la voiture sur le pont
10) élever le pont
11 mesurer la pression du pneu avant gauche
12) baisser le pont
13) retirer le voiture du pont
14) garer la voiture dans le parking
...

de plus pour connaître les colonnes qui ont changées il suffit d'une seule
fonctions, COLUMNS_UPDATED() dont le fonctionnement est décrit ici :
http://sqlpro.developpez.com/cours/sqlserver/transactsql/#L5.3.2
elle nécessite un masque binaire.

Enfin, l'affectation de différentes variables se fait d'un bloc et non
comme tu le veut... ça c'est casse gueule :
set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
car s'il y a plusieurs lignes cela plante !

EN CONCLUSION :
que veut tu faire d'un point de vu fonctionnel ? De l'archivage ?? De la
traçabilité ???

A +


--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste Delphi, web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************

Jerome a écrit:

Bonjour à tous,

j'ai un pb avec un If où je souhaite comparer des données d'entrée dans
un formulaire et les données de sorties pour déclencher une mise à jour
des champs via une procédure stockée.
Dans un trigger (ci-dessous) je place dans des variables les données
issues des tables Inserted et Deleted pour ensuite les comparer. Et là,
le test IF ne fonctionne pas, je ne passe pas le IF bien que j'ai des
valeurs de champs qui ont changées
Si quelqu'un pouvait m'éclairer sur ce pb. Est ce un pb dans
l'utilisation des tables Inserted - deleted ? L'erreur se trouve-t-elle
dans ce code ou dois je chercher ailleurs ?

-------------------------------------------------------------------
CREATE TRIGGER convert_clarion_sql_diffusion ON [dbo].[DFIC_DIFFUSION]
FOR INSERT, UPDATE
AS
declare @DateAncienne1 int
declare @DateAncienne2 int
declare @DateAConvertir1 int
declare @DateAConvertir2 int
declare @DateSQLConvertie1 datetime
declare @DateSQLConvertie2 datetime

set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
set @DateAConvertir2 = (select DDIF_DATE_EMISS from inserted)

set @DateAncienne1 = (select DDIF_DTE_DIFFUSIO from deleted)
set @DateAncienne2 = (select DDIF_DATE_EMISS from deleted)


if ((@DateAConvertir1 <> @DateAncienne1) OR (@DateAConvertir2 <>
@DateAncienne2) )
begin
execute DateClarionSQL @DateAConvertir1, @DateSQL = @DateSQLConvertie1
output
execute DateClarionSQL @DateAConvertir2, @DateSQL = @DateSQLConvertie2
output
...
--------------------------------------------------------------------------------------

Merci pour votre aide

Jerome









Avatar
Jean-Nicolas BERGER
Il me semble lire souvent que les SGBDR sont là pour contenir des
informations, mais pas pour s'occuper de leur mise en forme (décoration).
Selon moi, ce n'est donc pas à ta base de données de chercher à comprendre
comment mettre en forme ce qu'on lui donne, mais bien à ta couche
applicative de faire la conversion qui va bien, tandis que ta couche MSSQL
ne devrait voir que des datetime...
JN.




"Jerome" <a000@~yahoo.fr> a écrit dans le message de news:
d7f6d6$2la$
Merci pour ta réponse

D'un point de vue fonctionnel, j'ai une application Windows et une PHP qui
communique sur la même base MSSQL. Pour des raisons spécifiques, l'appli
Windows utilise des dates en format Numérique (du type 74400 par exemple)
et l'appli PHP des dates au format datetime.
Aussi, quand l'appli Windows renseigne un masque de saisie et valide donc
un enregistrement (en création ou modif), je souhaitais mettre à jour la
date pour la version PHP et vice et versa.

Au début, l'appli PHP était en consultation simple et ce principe
fonctionnait dan sle sens de la mise à jour des dates de la version
Windows vers les dates format Datetime
Maintenant l'appli PHP peut modifier les données, je vouslais donc tester
dans ce trigger d'où venait la modif afin de déclencher la mise à jour des
dates Windows ou des dates Datetime, d'où ce test sur les tables Inserted
et Deleted. Dans mon cas de figure, je n'ai qu'un seul enregistrement pris
en compte à chaque fois.

Jerome


"Fred BROUARD" a écrit dans le message de
news:
Un trigger ne s'exécute qu'UNE SEULE FOIS quelque soit le nombre de
lignes impacté par l'ordre.

Autrement dit, si l'ordre SQL suivant :
DELETE FROM MaTable
supprime 3 millions de lignes, alors le trigger FOR DELETE ne sera
déclenché qu'une seule fois et non pas trois millions de fois (et
heureusement !).

Donc, dès que je voit une variable locale dans un trigger => le mec qui a
écrit ce code n'a rien compris aux triggers !

Le code d'un trigger doit être ensembliste => pas de variable locale,
sauf dans une boucle de curseur.

De plus comparer colonne à colonne va faire exploser le cout du trigger
et les performances seront lamentables à bloquante !!!
Imagine que pour faire une révison sur une voiture le mécanicien s'y
prenne de cette manière :
1) rentrer dans le garage la voiture qui se trouve dans le parking
2) mettre la voiture sur le pont
3) élever le pont
4) mesurer la pression du pneu avant droit
5) baisser le pont
6) retirer le voiture du pont
7) garer la voiture dans le parking
8) rentrer dans le garage la voiture qui se trouve dans le parking
9) mettre la voiture sur le pont
10) élever le pont
11 mesurer la pression du pneu avant gauche
12) baisser le pont
13) retirer le voiture du pont
14) garer la voiture dans le parking
...

de plus pour connaître les colonnes qui ont changées il suffit d'une
seule fonctions, COLUMNS_UPDATED() dont le fonctionnement est décrit ici
: http://sqlpro.developpez.com/cours/sqlserver/transactsql/#L5.3.2
elle nécessite un masque binaire.

Enfin, l'affectation de différentes variables se fait d'un bloc et non
comme tu le veut... ça c'est casse gueule :
set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
car s'il y a plusieurs lignes cela plante !

EN CONCLUSION :
que veut tu faire d'un point de vu fonctionnel ? De l'archivage ?? De la
traçabilité ???

A +


--
Frédéric BROUARD, MVP SQL Server. Expert SQL / spécialiste Delphi, web
Livre SQL - col. Référence : http://sqlpro.developpez.com/bookSQL.html
Le site du SQL, pour débutants et pros : http://sqlpro.developpez.com
************************ www.datasapiens.com *************************

Jerome a écrit:
Bonjour à tous,

j'ai un pb avec un If où je souhaite comparer des données d'entrée dans
un formulaire et les données de sorties pour déclencher une mise à jour
des champs via une procédure stockée.
Dans un trigger (ci-dessous) je place dans des variables les données
issues des tables Inserted et Deleted pour ensuite les comparer. Et là,
le test IF ne fonctionne pas, je ne passe pas le IF bien que j'ai des
valeurs de champs qui ont changées
Si quelqu'un pouvait m'éclairer sur ce pb. Est ce un pb dans
l'utilisation des tables Inserted - deleted ? L'erreur se trouve-t-elle
dans ce code ou dois je chercher ailleurs ?

-------------------------------------------------------------------
CREATE TRIGGER convert_clarion_sql_diffusion ON [dbo].[DFIC_DIFFUSION]
FOR INSERT, UPDATE
AS
declare @DateAncienne1 int
declare @DateAncienne2 int
declare @DateAConvertir1 int
declare @DateAConvertir2 int
declare @DateSQLConvertie1 datetime
declare @DateSQLConvertie2 datetime

set @DateAConvertir1 = (select DDIF_DTE_DIFFUSIO from inserted)
set @DateAConvertir2 = (select DDIF_DATE_EMISS from inserted)

set @DateAncienne1 = (select DDIF_DTE_DIFFUSIO from deleted)
set @DateAncienne2 = (select DDIF_DATE_EMISS from deleted)


if ((@DateAConvertir1 <> @DateAncienne1) OR (@DateAConvertir2 <>
@DateAncienne2) )
begin
execute DateClarionSQL @DateAConvertir1, @DateSQL = @DateSQLConvertie1
output
execute DateClarionSQL @DateAConvertir2, @DateSQL = @DateSQLConvertie2
output
...
--------------------------------------------------------------------------------------

Merci pour votre aide

Jerome