Solved

SQL Delete Trigger works for single row delete only

Posted on 2011-09-19
11
330 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
  • 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
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 
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

Enterprise Mobility and BYOD For Dummies

Like “For Dummies” books, you can read this in whatever order you choose and learn about mobility and BYOD; and how to put a competitive mobile infrastructure in place. Developed for SMBs and large enterprises alike, you will find helpful use cases, planning, and implementation.

Question has a verified solution.

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

Suggested Solutions

JSON is being used more and more, besides XML, and you surely wanted to parse the data out into SQL instead of doing it in some Javascript. The below function in SQL Server can do the job for you, returning a quick table with the parsed data.
Ever needed a SQL 2008 Database replicated/mirrored/log shipped on another server but you can't take the downtime inflicted by initial snapshot or disconnect while T-logs are restored or mirror applied? You can use SQL Server Initialize from Backup…
This videos aims to give the viewer a basic demonstration of how a user can query current session information by using the SYS_CONTEXT function
Viewers will learn how the fundamental information of how to create a table.

825 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