OVH Cloud OVH Cloud

Create Trigger ...

4 réponses
Avatar
SuperGolgoth
Bonjour a tous,
Je reviens vers vous aujourd'hui avec une petite question concernant la
syntaxe du 'CREATE TRIGGER' ...
Dans le merveilleux livre de notre ami Frédéric Brouard, en page 282,
il est préciser l'option 'FOR EACH ROW' ... qui n'existe pas en SQL2000
...
Alors bien logiquement, ma question est :
Mais comment faire pour eviter ce message :

Error: La sous-requête a retourné plusieurs valeurs. Cela n'est pas
autorisé quand la sous-requête suit =, !=, <, <= , >, >= ou quand elle
est utilisée en tant qu'expression. (State:21000, Native Code: 200)
Error: L'instruction a été arrêtée. (State:01000, Native Code: E25)
This command did not return data, and it did not return any rows

Merci de votre aide

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Life is simple :
Eat, sleep, and surf the net
~~~~~~~~~~~~~~~~~~~~~~~~~~~

4 réponses

Avatar
Patrice
Typiquement tu as quelque chose de la forme :

...WHERE Colonne2=(SELECT Colonne FROM AutreTable)

Si la sous-requête retourne plusieurs ligne, l'opérateur n'a pas de sens.
Donc utiliser IN, une jointure etc...

Notamment dans un trigger tu peux avoir plusieurs lignes dans les
pseudo-tables. La partie concernée de ton code SQL serait utile pour aller
plus avant...

Patrice


--

"SuperGolgoth" a écrit dans le message de
news:
Bonjour a tous,
Je reviens vers vous aujourd'hui avec une petite question concernant la
syntaxe du 'CREATE TRIGGER' ...
Dans le merveilleux livre de notre ami Frédéric Brouard, en page 282,
il est préciser l'option 'FOR EACH ROW' ... qui n'existe pas en SQL2000
...
Alors bien logiquement, ma question est :
Mais comment faire pour eviter ce message :

Error: La sous-requête a retourné plusieurs valeurs. Cela n'est pas
autorisé quand la sous-requête suit =, !=, <, <= , >, >= ou quand elle
est utilisée en tant qu'expression. (State:21000, Native Code: 200)
Error: L'instruction a été arrêtée. (State:01000, Native Code: E25)
This command did not return data, and it did not return any rows

Merci de votre aide

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Life is simple :
Eat, sleep, and surf the net
~~~~~~~~~~~~~~~~~~~~~~~~~~~



Avatar
SuperGolgoth
Patrice avait énoncé :
Typiquement tu as quelque chose de la forme :

...WHERE Colonne2=(SELECT Colonne FROM AutreTable)

Si la sous-requête retourne plusieurs ligne, l'opérateur n'a pas de sens.
Donc utiliser IN, une jointure etc...

Notamment dans un trigger tu peux avoir plusieurs lignes dans les
pseudo-tables. La partie concernée de ton code SQL serait utile pour aller
plus avant...

Patrice



Je peux faire mieux ... je vous livre le code complet avec la
'possible' solution a base de FETCH NEXT ...
Par contre j'ai maintenant un autre probleme ... lorsque la variable
@message depasse 4000 cars ... comment faire pour allez au dela de
cette limite ?
Merci



CREATE TRIGGER gstock_alertes ON scheme.stockm
AFTER UPDATE AS
DECLARE @FROM NVARCHAR(4000),
@FROM_NAME NVARCHAR(4000),
@TO NVARCHAR(4000),
@replyto NVARCHAR(4000),
@CC NVARCHAR(4000),
@BCC NVARCHAR(4000),
@priority NVARCHAR(10),
@subject NVARCHAR(1000),
@message NVARCHAR(4000),
@type NVARCHAR(100),
@attachments NVARCHAR(4000),
@codepage INT,
@rc INT,
@couleur NVARCHAR(100),
@product varchar(12),
@long_description varchar(40),
@physical_qty int,
@on_order_qty int,
@back_order_qty int,
@min_stock_level int,
@safety_stock_level int

DECLARE gstock_cursor CURSOR FOR
select product, long_description, physical_qty, on_order_qty,
back_order_qty, min_stock_level, safety_stock_level
from inserted
where warehouse = '1G' and ((physical_qty + on_order_qty <
min_stock_level) or (physical_qty + on_order_qty < safety_stock_level)
or (back_order_qty <> 0))

SET @FROM = N''
SET @FROM_NAME = N'Serveur SQL'
SET @TO = N''
SET @replyto = N''
SET @CC = N''
SET @BCC = N''
SET @priority = N'High'
SET @subject = N'Gestion du stock'
SET @type = N'text/html'
SET @message = '<html><head><title>Gestion de
stock</title><meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
</head><body bgcolor="#FFFFFF"
text="#000000"><H1><u>GESTION DU STOCK</u></H1><H2>Bonjour,</H2>Suite à
une commande, le stock pour le (ou les) produit(s) suivant atteint une
cote d''alerte :<BR><BR>
<table width="100%" border="1"><tr bgcolor="#CCCCCC">
<td><b><font size="2">PRODUIT</font></b></td>
<td><b><font size="2">DESCRIPTION</font></b></td>
<td><b><font size="2"><div align="center">QTé
PHY.</div></font></b></td>
<td><b><font size="2"><div
align="center">COMMANDE</div></font></b></td>
<td><b><font size="2"><div
align="center">B.O.</div></font></b></td>
<td><b><font size="2"><div align="center">ALERTE
VERTE</div></font></b></td>
<td><b><font size="2"><div align="center">ALERTE
ROUGE</div></font></b></td></tr>'
OPEN gstock_cursor
FETCH NEXT FROM gstock_cursor
INTO @product, @long_description, @physical_qty, @on_order_qty,
@back_order_qty, @min_stock_level, @safety_stock_level

WHILE @@FETCH_STATUS = 0
BEGIN
IF @physical_qty + @on_order_qty < @min_stock_level SET
@couleur = N'bgcolor="#99FF99"'
IF @physical_qty + @on_order_qty < @safety_stock_level SET
@couleur = 'bgcolor="#FF9693"'
IF @back_order_qty <> 0 SET @couleur = 'bgcolor="#99FFFF"'
SELECT @message = @message + '<tr ',
@message = @message + @couleur,
@message = @message + '><td><font size="2">',
@message = @message + @product,
@message = @message + '</font></td><td><font size="2">',
@message = @message + @long_description,
@message = @message + '</font></td><td><font size="2"><div
align="center">',
@message = @message + RTRIM(CONVERT(varchar(5),
@physical_qty)),
@message = @message + '</div></font></td><td><font
size="2"><div align="center">',
@message = @message + RTRIM(CONVERT(varchar(5),
@on_order_qty)),
@message = @message + '</div></font></td><td><font
size="2"><div align="center">',
@message = @message + RTRIM(CONVERT(varchar(5),
@back_order_qty)),
@message = @message + '</div></font></td><td><font
size="2"><div align="center">',
@message = @message + RTRIM(CONVERT(varchar(5),
@min_stock_level)),
@message = @message + '</div></font></td><td><font
size="2"><div align="center">',
@message = @message + RTRIM(CONVERT(varchar(5),
@safety_stock_level)),
@message = @message + '</div></font></td></tr>'
FETCH NEXT FROM gstock_cursor
INTO @product, @long_description, @physical_qty,
@on_order_qty, @back_order_qty, @min_stock_level, @safety_stock_level
CONTINUE
END
SET @message = @message + '</table><BR>Merci de réagir en
fonction.<BR>Cordialement.</body></html>'
SET @attachments = N''
SET @codepage = 0
CLOSE gstock_cursor
DEALLOCATE gstock_cursor

IF EXISTS (SELECT product FROM inserted WHERE warehouse = '1G'
and (physical_qty + on_order_qty < min_stock_level) or (physical_qty +
on_order_qty < safety_stock_level) or (back_order_qty <> 0) )
EXEC @rc = master.dbo.xp_smtp_sendmail
@FROM = @FROM,
@FROM_NAME = @FROM_NAME,
@TO = @TO,
@replyto = @replyto,
@CC = @CC,
@BCC = @BCC,
@priority = @priority,
@subject = @subject,
@message = @message,
@type = @type,
@attachments = @attachments,
@codepage = @codepage,
@server = N'smtp.bmd-net.com'

SELECT RC = @rc

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Life is simple :
Eat, sleep, and surf the net
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Avatar
SuperGolgoth
Je precise que ce trigger fonctionne tres bien lorsque je fais une
requete d'update sur la table , mais par contre lorsque j'utilise
l'application pour generer une commande (donc modification du stock)
j'ai un plantage ...
Je pense donc qu'il y a un conflit quelque part, est-ce que l'appli se
reserve la table en exclusif ...?
c'est d'autant plus bizarre que je ne fais que lire la table des stock,
donc je ne devrais gener personne non ?
Merci de me donner vos avis ...

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Life is simple :
Eat, sleep, and surf the net
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Avatar
Fred BROUARD
bonjour,

ce n'est pas très bon de faire un trigger qui fait du fonctionnel. Un trigger
est là pour faire du relationnel et palier certains des manques des modèles
relationnel. Si tu veut réellement gérer finement un trigger, alors sort du
trigger LE PLUS TÔT POSSIBLE, quitte à utiliser une SP.

lorsque je voit une SP avec 30 variables locales, là déjà je sais qu'il y a un
problème. Quand en plus on y fait du HTML dedans, je sais que l'application va
être une catastrophe. Les triggers sont les objets qui font le plus tomber les
performances... De surcroit s'il y a un curseur, c'est que la personne ne sait
visiblement pas faire des requêtes...

Explique nous ce que tu veut faire...

A +


SuperGolgoth a écrit:
Patrice avait énoncé :

Typiquement tu as quelque chose de la forme :

...WHERE Colonne2=(SELECT Colonne FROM AutreTable)

Si la sous-requête retourne plusieurs ligne, l'opérateur n'a pas de sens.
Donc utiliser IN, une jointure etc...

Notamment dans un trigger tu peux avoir plusieurs lignes dans les
pseudo-tables. La partie concernée de ton code SQL serait utile pour
aller
plus avant...

Patrice



Je peux faire mieux ... je vous livre le code complet avec la 'possible'
solution a base de FETCH NEXT ...
Par contre j'ai maintenant un autre probleme ... lorsque la variable
@message depasse 4000 cars ... comment faire pour allez au dela de cette
limite ?
Merci



CREATE TRIGGER gstock_alertes ON scheme.stockm
AFTER UPDATE AS
DECLARE @FROM NVARCHAR(4000),
@FROM_NAME NVARCHAR(4000),
@TO NVARCHAR(4000),
@replyto NVARCHAR(4000),
@CC NVARCHAR(4000),
@BCC NVARCHAR(4000),
@priority NVARCHAR(10),
@subject NVARCHAR(1000),
@message NVARCHAR(4000),
@type NVARCHAR(100),
@attachments NVARCHAR(4000),
@codepage INT,
@rc INT,
@couleur NVARCHAR(100),
@product varchar(12),
@long_description varchar(40),
@physical_qty int,
@on_order_qty int,
@back_order_qty int,
@min_stock_level int,
@safety_stock_level int

DECLARE gstock_cursor CURSOR FOR
select product, long_description, physical_qty, on_order_qty,
back_order_qty, min_stock_level, safety_stock_level
from inserted
where warehouse = '1G' and ((physical_qty + on_order_qty <
min_stock_level) or (physical_qty + on_order_qty < safety_stock_level)
or (back_order_qty <> 0))

SET @FROM = N''
SET @FROM_NAME = N'Serveur SQL'
SET @TO = N''
SET @replyto = N''
SET @CC = N''
SET @BCC = N''
SET @priority = N'High'
SET @subject = N'Gestion du stock'
SET @type = N'text/html'
SET @message = '<html><head><title>Gestion de
stock</title><meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
</head><body bgcolor="#FFFFFF"
text="#000000"><H1><u>GESTION DU STOCK</u></H1><H2>Bonjour,</H2>Suite à
une commande, le stock pour le (ou les) produit(s) suivant atteint une
cote d''alerte :<BR><BR>
<table width="100%" border="1"><tr bgcolor="#CCCCCC">
<td><b><font size="2">PRODUIT</font></b></td>
<td><b><font size="2">DESCRIPTION</font></b></td>
<td><b><font size="2"><div align="center">QTé
PHY.</div></font></b></td>
<td><b><font size="2"><div
align="center">COMMANDE</div></font></b></td>
<td><b><font size="2"><div
align="center">B.O.</div></font></b></td>
<td><b><font size="2"><div align="center">ALERTE
VERTE</div></font></b></td>
<td><b><font size="2"><div align="center">ALERTE
ROUGE</div></font></b></td></tr>'
OPEN gstock_cursor
FETCH NEXT FROM gstock_cursor
INTO @product, @long_description, @physical_qty, @on_order_qty,
@back_order_qty, @min_stock_level, @safety_stock_level

WHILE @@FETCH_STATUS = 0
BEGIN
IF @physical_qty + @on_order_qty < @min_stock_level SET @couleur
= N'bgcolor="#99FF99"'
IF @physical_qty + @on_order_qty < @safety_stock_level SET
@couleur = 'bgcolor="#FF9693"'
IF @back_order_qty <> 0 SET @couleur = 'bgcolor="#99FFFF"'
SELECT @message = @message + '<tr ',
@message = @message + @couleur,
@message = @message + '><td><font size="2">',
@message = @message + @product,
@message = @message + '</font></td><td><font size="2">',
@message = @message + @long_description,
@message = @message + '</font></td><td><font size="2"><div
align="center">',
@message = @message + RTRIM(CONVERT(varchar(5), @physical_qty)),
@message = @message + '</div></font></td><td><font
size="2"><div align="center">',
@message = @message + RTRIM(CONVERT(varchar(5), @on_order_qty)),
@message = @message + '</div></font></td><td><font
size="2"><div align="center">',
@message = @message + RTRIM(CONVERT(varchar(5), @back_order_qty)),
@message = @message + '</div></font></td><td><font
size="2"><div align="center">',
@message = @message + RTRIM(CONVERT(varchar(5),
@min_stock_level)),
@message = @message + '</div></font></td><td><font
size="2"><div align="center">',
@message = @message + RTRIM(CONVERT(varchar(5),
@safety_stock_level)),
@message = @message + '</div></font></td></tr>'
FETCH NEXT FROM gstock_cursor
INTO @product, @long_description, @physical_qty, @on_order_qty,
@back_order_qty, @min_stock_level, @safety_stock_level
CONTINUE
END
SET @message = @message + '</table><BR>Merci de réagir en
fonction.<BR>Cordialement.</body></html>'
SET @attachments = N''
SET @codepage = 0
CLOSE gstock_cursor
DEALLOCATE gstock_cursor

IF EXISTS (SELECT product FROM inserted WHERE warehouse = '1G' and
(physical_qty + on_order_qty < min_stock_level) or (physical_qty +
on_order_qty < safety_stock_level) or (back_order_qty <> 0) )
EXEC @rc = master.dbo.xp_smtp_sendmail
@FROM = @FROM,
@FROM_NAME = @FROM_NAME,
@TO = @TO,
@replyto = @replyto,
@CC = @CC,
@BCC = @BCC,
@priority = @priority,
@subject = @subject,
@message = @message,
@type = @type,
@attachments = @attachments,
@codepage = @codepage,
@server = N'smtp.bmd-net.com'

SELECT RC = @rc




--
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 *************************