Solved

SQL Delete Trigger works for single row delete only

Posted on 2011-09-19
11
343 Views
Last Modified: 2012-05-12
This SP works for a single row operation only... Any ideas?

IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'AuthCodeToDeviceSettings3' AND type = 'TR')
DROP TRIGGER  AuthCodeToDeviceSettings3
GO
CREATE TRIGGER AuthCodeToDeviceSettings3 ON [AuthCodes]
FOR DELETE
AS

DECLARE @AuthCodesID As INT
DECLARE @DeviceID As INT
DECLARE @DatabaseValue As INT
SELECT @AuthCodesID = (SELECT AuthCodesID FROM Deleted)
SELECT @DeviceID = (SELECT DeviceID FROM  Deleted WHERE [AuthCodesID] = @AuthCodesID)
SELECT @DatabaseValue = (SELECT [DatabaseValue] FROM [DeviceSettings] WHERE [DeviceID] = @DeviceID AND [ItemName] = '!TabUser' AND [DatabaseValue] > 0 )


BEGIN
UPDATE [dbo].[DeviceSettings]
     SET
                  [DatabaseValue] = (@DatabaseValue + 1)
     WHERE
                  [DeviceID] = @DeviceID AND [ItemName] = '!TabUser' AND [DatabaseValue] > 0        
IF @@ROWCOUNT=0
    UPDATE [dbo].[DeviceSettings]
     SET
                  [DatabaseValue] = 1
     WHERE
                  [DeviceID] = @DeviceID AND [ItemName] = '!TabUser'
END
GO
0
Comment
Question by:MBoy
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 3
  • 2
11 Comments
 
LVL 39

Expert Comment

by:Pratima Pharande
ID: 36559095
try this

IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'AuthCodeToDeviceSettings3' AND type = 'TR')
DROP TRIGGER  AuthCodeToDeviceSettings3
GO
CREATE TRIGGER AuthCodeToDeviceSettings3 ON [AuthCodes]
FOR DELETE
AS

BEGIN
UPDATE [dbo].[DeviceSettings]
     SET
                  [DatabaseValue] = [DatabaseValue] + 1
     WHERE
                  [DeviceID] in

 (SELECT DeviceID FROM  Deleted )

AND [ItemName] = '!TabUser' AND [DatabaseValue] > 0        


IF @@ROWCOUNT=0
    UPDATE [dbo].[DeviceSettings]
     SET
                  [DatabaseValue] = 1
     WHERE
                  [DeviceID] in

 (SELECT DeviceID FROM  Deleted ) AND [ItemName] = '!TabUser'
END
GO
0
 
LVL 39

Expert Comment

by:Pratima Pharande
ID: 36559103
your code is not working for all records b'coz

SELECT @AuthCodesID = (SELECT AuthCodesID FROM Deleted)
SELECT @DeviceID = (SELECT DeviceID FROM  Deleted WHERE [AuthCodesID] = @AuthCodesID)
SELECT @DatabaseValue = (SELECT [DatabaseValue] FROM [DeviceSettings] WHERE [DeviceID] = @DeviceID AND [ItemName] = '!TabUser' AND [DatabaseValue] > 0 )

this will gives you only first record from deleted

when multiple records are deleted will come all together is deleted table
0
 
LVL 8

Expert Comment

by:raulggonzalez
ID: 36559120
Hi, your problem is how you use DELETED table

when you do

SELECT @AuthCodesID = (SELECT AuthCodesID FROM Deleted)

you can only keep one value in @AuthCodesID because is just a variable, so you execute the update just for one value...

You have to look for the way of looping through DELETED table to use all the values in there.

0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 8

Expert Comment

by:raulggonzalez
ID: 36559131
Please try something like this

IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'AuthCodeToDeviceSettings3' AND type = 'TR')
DROP TRIGGER  AuthCodeToDeviceSettings3
GO
CREATE TRIGGER AuthCodeToDeviceSettings3 ON [AuthCodes]
FOR DELETE
AS
BEGIN
      UPDATE [dbo].[DeviceSettings]
            SET [DatabaseValue] = ISNULL([DatabaseValue], 0)
            WHERE [DeviceID] = (SELECT DeviceID
                                                FROM  Deleted
                                                WHERE [AuthCodesID] = (SELECT AuthCodesID FROM Deleted))
                  AND [ItemName] = '!TabUser' AND [DatabaseValue] > 0        

GO
0
 
LVL 8

Expert Comment

by:raulggonzalez
ID: 36559133
Sorry, last condition is no needed

IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'AuthCodeToDeviceSettings3' AND type = 'TR')
DROP TRIGGER  AuthCodeToDeviceSettings3
GO
CREATE TRIGGER AuthCodeToDeviceSettings3 ON [AuthCodes]
FOR DELETE
AS
BEGIN
      UPDATE [dbo].[DeviceSettings]
            SET [DatabaseValue] = ISNULL([DatabaseValue], 0)
            WHERE [DeviceID] = (SELECT DeviceID
                                                FROM  Deleted
                                                WHERE [AuthCodesID] = (SELECT AuthCodesID FROM Deleted))
                  AND [ItemName] = '!TabUser'

GO
0
 
LVL 8

Expert Comment

by:raulggonzalez
ID: 36559141
Again... this should be the final :)


IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'AuthCodeToDeviceSettings3' AND type = 'TR')
DROP TRIGGER  AuthCodeToDeviceSettings3
GO
CREATE TRIGGER AuthCodeToDeviceSettings3 ON [AuthCodes]
FOR DELETE
AS
BEGIN
	UPDATE [dbo].[DeviceSettings]
		SET [DatabaseValue] = ISNULL([DatabaseValue], 0) + 1
		WHERE [DeviceID] = (SELECT DeviceID 
								FROM  Deleted 
								WHERE [AuthCodesID] = (SELECT AuthCodesID FROM Deleted)) 
			AND [ItemName] = '!TabUser'

GO

Open in new window

0
 
LVL 39

Accepted Solution

by:
Pratima Pharande earned 500 total points
ID: 36559158
IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'AuthCodeToDeviceSettings3' AND type = 'TR')
DROP TRIGGER  AuthCodeToDeviceSettings3
GO
CREATE TRIGGER AuthCodeToDeviceSettings3 ON [AuthCodes]
FOR DELETE
AS

BEGIN
UPDATE DV
     SET
                  DV.[DatabaseValue] = DV.[DatabaseValue] + 1

From [dbo].[DeviceSettings] DV
Inner join Deleted D on DV.[DeviceID] = D.[DeviceID]
     WHERE
                 AND DV.[ItemName] = '!TabUser' AND DV.[DatabaseValue] > 0        


IF @@ROWCOUNT=0
    UPDATE DV
     SET
                  DV.[DatabaseValue] = 1

From [dbo].[DeviceSettings] DV
Inner join Deleted D on DV.[DeviceID] = D.[DeviceID]
     WHERE
                 AND DV.[ItemName] = '!TabUser' AND DV.[DatabaseValue] > 0        

END
GO
0
 
LVL 8

Expert Comment

by:raulggonzalez
ID: 36559180
Hi, I couldn't test my solution  (obviously) but I really think that there's no need to have 2 different UPDATES.

The first UPDATE just differs from the second on the condition (DatabaseValue > 0), so I assumed that was because maybe DatabaseValue can be NULL, so NULL + 1 = NULL... that's why I put ISNULL(), to avoid it.

Probably #pratima_mcs' idea about the JOIN is fine but should work the same like the subqueries.

Hope you can make it.

cheers
0
 
LVL 3

Author Comment

by:MBoy
ID: 36559727
I'm on Asian time but I will check these tomorrow morning - Thanks
0
 
LVL 3

Author Closing Comment

by:MBoy
ID: 36564587
Thanks
0
 
LVL 8

Expert Comment

by:raulggonzalez
ID: 36566177
Hi,

I think I'm not wrong if I say that the solution you accepted is buggy, because both UPDATE have exactly the same WHERE clause. (Apart from the syntax error)

1st update

     WHERE -- missing condition
                 AND DV.[ItemName] = '!TabUser' AND DV.[DatabaseValue] > 0  

2nd update
WHERE -- missing condition
                 AND DV.[ItemName] = '!TabUser' AND DV.[DatabaseValue] > 0 -- same condition as the first so same set of rows will be affected (zero)


So if you execute the first UPDATE and @@ROWCOUNT = 0 then you execute the second UPDATE which will affect the same set of records, so ZERO records will be updated.

Please review it.
0

Featured Post

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Use this article to create a batch file to backup a Microsoft SQL Server database to a Windows folder.  The folder can be on the local hard drive or on a network share.  This batch file will query the SQL server to get the current date & time and wi…
I have a large data set and a SSIS package. How can I load this file in multi threading?
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
Via a live example, show how to extract insert data into a SQL Server database table using the Import/Export option and Bulk Insert.

738 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question