Solved

SQL Delete Trigger works for single row delete only

Posted on 2011-09-19
11
320 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
 
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
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.

 
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

VMware Disaster Recovery and Data Protection

In this expert guide, you’ll learn about the components of a Modern Data Center. You will use cases for the value-added capabilities of Veeam®, including combining backup and replication for VMware disaster recovery and using replication for data center migration.

Question has a verified solution.

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

This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
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…
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…
This video shows, step by step, how to configure Oracle Heterogeneous Services via the Generic Gateway Agent in order to make a connection from an Oracle session and access a remote SQL Server database table.

929 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now