I used the SQL query analyser
here is the result set
way i read that is the update is done first then the delete
Specifies that the trigger is fired only when all operations specified in the triggering SQL statement have executed successfully.
Your code is the trigger.
The SQL containing the DELETE statement is the triggering SQL.
The DELETE takes place FIRST!!!!! That is why there is a DELETED and an INSERTED result set to work with.
Here is some proof.
This SQL will create a DB, a table, add a trigger.
/****** Object: Database Dummy Script Date: 24/01/2006 13:07:38 ******/
IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = N'Dummy')
DROP DATABASE [Dummy]
GO
CREATE DATABASE [Dummy] ON (NAME = N'Dummy_Data', FILENAME = N'D:\Data\SQL 2000\MSSQL\Data\Dummy_Data.MDF' , SIZE = 1, FILEGROWTH = 10%) LOG ON (NAME = N'Dummy_Log', FILENAME = N'D:\Data\SQL 2000\MSSQL\Data\Dummy_Log.LDF' , SIZE = 1, FILEGROWTH = 10%)
COLLATE Latin1_General_CI_AS
GO
exec sp_dboption N'Dummy', N'autoclose', N'false'
GO
exec sp_dboption N'Dummy', N'bulkcopy', N'false'
GO
exec sp_dboption N'Dummy', N'trunc. log', N'false'
GO
exec sp_dboption N'Dummy', N'torn page detection', N'true'
GO
exec sp_dboption N'Dummy', N'read only', N'false'
GO
exec sp_dboption N'Dummy', N'dbo use', N'false'
GO
exec sp_dboption N'Dummy', N'single', N'false'
GO
exec sp_dboption N'Dummy', N'autoshrink', N'false'
GO
exec sp_dboption N'Dummy', N'ANSI null default', N'false'
GO
exec sp_dboption N'Dummy', N'recursive triggers', N'false'
GO
exec sp_dboption N'Dummy', N'ANSI nulls', N'false'
GO
exec sp_dboption N'Dummy', N'concat null yields null', N'false'
GO
exec sp_dboption N'Dummy', N'cursor close on commit', N'false'
GO
exec sp_dboption N'Dummy', N'default to local cursor', N'false'
GO
exec sp_dboption N'Dummy', N'quoted identifier', N'false'
GO
exec sp_dboption N'Dummy', N'ANSI warnings', N'false'
GO
exec sp_dboption N'Dummy', N'auto create statistics', N'true'
GO
exec sp_dboption N'Dummy', N'auto update statistics', N'true'
GO
if( (@@microsoftversion / power(2, 24) = 8) and (@@microsoftversion & 0xffff >= 724) )
exec sp_dboption N'Dummy', N'db chaining', N'false'
GO
use [Dummy]
GO
/****** Object: Trigger dbo.DeleteRowCount Script Date: 24/01/2006 13:07:39 ******/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[DeleteRowCount]') and OBJECTPROPERTY(id, N'IsTrigger') = 1)
drop trigger [dbo].[DeleteRowCount]
GO
/****** Object: Table [dbo].[DummyTable] Script Date: 24/01/2006 13:07:39 ******/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[DummyTable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[DummyTable]
GO
/****** Object: Table [dbo].[DummyTable] Script Date: 24/01/2006 13:07:39 ******/
CREATE TABLE [dbo].[DummyTable] (
[dummyID] [int] IDENTITY (1, 1) NOT NULL ,
[A_Timestamp] [timestamp] NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[DummyTable] WITH NOCHECK ADD
CONSTRAINT [PK_DummyTable] PRIMARY KEY CLUSTERED
(
[dummyID]
) ON [PRIMARY]
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
/****** Object: Trigger dbo.DeleteRowCount Script Date: 24/01/2006 13:07:39 ******/
CREATE TRIGGER DeleteRowCount ON [dbo].[DummyTable]
FOR DELETE
AS
/* First return the number of rows in the DELETED set */
SELECT
'Deleted Rows Count',
COUNT(*) AS [Count]
FROM
deleted
UNION
/* Then return the number of rows in the DummyTable */
SELECT
'DummyTable Rows Count',
COUNT(*) AS [Count]
FROM
DummyTable
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
Next, I insert 40 rows and then run a 3 specific queries.
[list=1]
- Show the number of rows in the table.
- Delete 1 row
- Show the number of rows in the table.
[/list:o]
/* Insert 40 records */
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
INSERT DummyTable(A_Timestamp) VALUES(DEFAULT)
/* How many rows do we have ? */
SELECT COUNT(*) AS [Before Delete] FROM DummyTable
/* Delete one of them */
DELETE FROM DummyTable WHERE DummyID=1
/* How many rows do we have now ? */
SELECT COUNT(*) AS [After Delete] FROM DummyTable
You will see that whilst executing the trigger, the row has already been deleted and therefore cannot be accessed.
My result sets for the 3 specific queries are :
Set 1:
Returns 1 row with 1 column.
Column 1, Row is "40.00"
Set 2:
Returns 2 rows with 2 columns.
Column 1, Row 1 is "Deleted Rows Count"
Column 2, Row 1 is "1.00"
Column 1, Row 2 is "DummyTable Rows Count"
Column 2, Row 2 is "39.00"
Set 3:
Returns 1 row with 1 column.
Column 1, Row is "39.00"
If I alter the delete query to now say
/* How many rows do we have ? */
SELECT COUNT(*) AS [Before Delete] FROM DummyTable
/* Delete one of them */
DELETE FROM DummyTable WHERE DummyID<10
/* How many rows do we have now ? */
SELECT COUNT(*) AS [After Delete] FROM DummyTable
The results are:
Set 1:
Returns 1 row with 1 column.
Column 1, Row is "39.00"
Set 2:
Returns 2 rows with 2 columns.
Column 1, Row 1 is "Deleted Rows Count"
Column 2, Row 1 is "8.00"
Column 1, Row 2 is "DummyTable Rows Count"
Column 2, Row 2 is "31.00"
Set 3:
Returns 1 row with 1 column.
Column 1, Row is "31.00"
This shows that you cannot look at the source table when you are deleting data. You can only look at the DELETED table as this contains the deleted rows.