Showing posts with label trigger. Show all posts
Showing posts with label trigger. Show all posts

Friday, March 30, 2012

Inserted/deleted table.

Hi,

I am currently working on a MS SQL server 2000.

I would like to access the data inserted or deleted within a trigger. however the built-in tables -- inserted and deleted -- are not accessible. anyone knows why? And is there any other way to do this?

Thankspost your t-sql code that you used to access the inserted/deleted tablessql

INSERTED table performance

I have a table with one UPDATE trigger. When I execute a one row update
command
to the table, Graphical Query Plan reports very slow select from INSERTED
table (900ms).
However, if I check the same command using Profiler, everything goes quickly
(duration 0 ms). Why is that? Which one should I trust, profiler or query
plan?I trust Profiler more than the Graphical Query Plan. I have seen some quite
strange costs and percentages in the Graphical Query Plan, specially when
objects are involved that don't exist at the beginning of the query, like
the inserted and deleted tables, temporary tables and table variables
--
Jacco Schalkwijk
SQL Server MVP
"Pexi" <pekkadotheimonen@.plenwaredotnospamdotcom> wrote in message
news:emPWAZ4rDHA.2444@.TK2MSFTNGP12.phx.gbl...
> I have a table with one UPDATE trigger. When I execute a one row update
> command
> to the table, Graphical Query Plan reports very slow select from INSERTED
> table (900ms).
> However, if I check the same command using Profiler, everything goes
quickly
> (duration 0 ms). Why is that? Which one should I trust, profiler or query
> plan?
>|||Pexi,
Something that surprise me when I first found out. Inserted and deleted do
not exist, but are virtual tables that are populated each time you query
them by scanning the transaction log to extract the before and after images.
This is why the suggestion is to fill temp tables #inserted and #deleted if
you need to make repeated use of these tables.
Regarding the difference in the timings, the best way to measure is to
create a test. Do a loop calling your UPDATE repeatedly and logging the
milliseconds in a table.
SET @.BeginTime = GetDate()
EXEC YourTestStatement
INSERT INTO TrackingTable Values(@.BeginTime, GetDate())
Afterward you can analyze the results (and publish an article).
Russell Fields
http://www.sqlpass.org/
2004 PASS Community Summit - Orlando
- The largest user-event dedicated to SQL Server!
"Pexi" <pekkadotheimonen@.plenwaredotnospamdotcom> wrote in message
news:emPWAZ4rDHA.2444@.TK2MSFTNGP12.phx.gbl...
> I have a table with one UPDATE trigger. When I execute a one row update
> command
> to the table, Graphical Query Plan reports very slow select from INSERTED
> table (900ms).
> However, if I check the same command using Profiler, everything goes
quickly
> (duration 0 ms). Why is that? Which one should I trust, profiler or query
> plan?
>|||Thanks for the replies! You kind of confirm my thinking:
never trust the query plan - it just tells fairy tales sometimes :)
pexi
"Pexi" <pekkadotheimonen@.plenwaredotnospamdotcom> wrote in message
news:emPWAZ4rDHA.2444@.TK2MSFTNGP12.phx.gbl...
> I have a table with one UPDATE trigger. When I execute a one row update
> command
> to the table, Graphical Query Plan reports very slow select from INSERTED
> table (900ms).
> However, if I check the same command using Profiler, everything goes
quickly
> (duration 0 ms). Why is that? Which one should I trust, profiler or query
> plan?
>

inserted table

Is it ever possible for the inserted table to have more than one row in a
for update trigger? One of our devs recently put a cursor in his for update
trigger to loop over rows in the inserted table. However, from what I
understand, inserted should never have more than one row in it. I just
wanted to verify this before I removed it as I am working on optimizing it.
Brent Black
Onvia.com
Technical Lead/Database AdministratorThe inserted table can indeed have > 1 row in it and you code should take
this into account. Likely, you don't need a cursor either.
Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"Brent Black" <bblack@.onvia.com> wrote in message
news:uhVRS4K9DHA.3404@.TK2MSFTNGP09.phx.gbl...
Is it ever possible for the inserted table to have more than one row in a
for update trigger? One of our devs recently put a cursor in his for update
trigger to loop over rows in the inserted table. However, from what I
understand, inserted should never have more than one row in it. I just
wanted to verify this before I removed it as I am working on optimizing it.
Brent Black
Onvia.com
Technical Lead/Database Administrator|||Don't use a cursor in a trigger, typically people do something like this:
update table set column = value where prinmarykey = (select primary key from
inserted)
If you will have multiple updates or inserts you would want to change it to
this
update table set column = value where prinmarykey IN (select primary key
from inserted)
HTH
--
Ray Higdon MCSE, MCDBA, CCNA
--
"Brent Black" <bblack@.onvia.com> wrote in message
news:uhVRS4K9DHA.3404@.TK2MSFTNGP09.phx.gbl...
> Is it ever possible for the inserted table to have more than one row in a
> for update trigger? One of our devs recently put a cursor in his for
update
> trigger to loop over rows in the inserted table. However, from what I
> understand, inserted should never have more than one row in it. I just
> wanted to verify this before I removed it as I am working on optimizing
it.
> Brent Black
> Onvia.com
> Technical Lead/Database Administrator
>|||I've been able to do that in every case except where the ID value from the
cursor is being passed into a udf that returns a table.. For example:
insert into sometable (column1, column2)
select distinct @.CursorValue, pgr.ID
from someUDF(@.CursorValue) as pgr
I tried changing this to:
insert into sometable(column1, column2)
select distinct i.ID, pgr.ID
from someUDF(i.ID) as pgr,
inserted i
but that didn't work because it expects a single deterministic value to be
passed into the UDL.. It appears that was why the original dev chose to use
a cursor in the trigger to handle this in the first place. Any ideas on how
to do this without the cursor?
Thanks!
Brent Black
Onvia.com
Technical Lead/Database Administrator
"Ray Higdon" <sqlhigdon@.nospam.yahoo.com> wrote in message
news:OYCx3KL9DHA.2604@.TK2MSFTNGP10.phx.gbl...
> Don't use a cursor in a trigger, typically people do something like this:
> update table set column = value where prinmarykey = (select primary key
from
> inserted)
> If you will have multiple updates or inserts you would want to change it
to
> this
> update table set column = value where prinmarykey IN (select primary key
> from inserted)
> HTH
> --
> Ray Higdon MCSE, MCDBA, CCNA
> --
> "Brent Black" <bblack@.onvia.com> wrote in message
> news:uhVRS4K9DHA.3404@.TK2MSFTNGP09.phx.gbl...
a
> update
> it.
>|||What's the UDF look like?
Ray Higdon MCSE, MCDBA, CCNA
--
"Brent Black" <bblack@.onvia.com> wrote in message
news:ucGCsKN9DHA.1936@.TK2MSFTNGP12.phx.gbl...
> I've been able to do that in every case except where the ID value from the
> cursor is being passed into a udf that returns a table.. For example:
> insert into sometable (column1, column2)
> select distinct @.CursorValue, pgr.ID
> from someUDF(@.CursorValue) as pgr
> I tried changing this to:
> insert into sometable(column1, column2)
> select distinct i.ID, pgr.ID
> from someUDF(i.ID) as pgr,
> inserted i
> but that didn't work because it expects a single deterministic value to
be
> passed into the UDL.. It appears that was why the original dev chose to
use
> a cursor in the trigger to handle this in the first place. Any ideas on
how
> to do this without the cursor?
> Thanks!
> Brent Black
> Onvia.com
> Technical Lead/Database Administrator
> "Ray Higdon" <sqlhigdon@.nospam.yahoo.com> wrote in message
> news:OYCx3KL9DHA.2604@.TK2MSFTNGP10.phx.gbl...
this:
> from
> to
in
> a
just
optimizing
>|||Brent,
I wouldn't be surprised if in this case the UDF is something like
create function someUDF(
@.v somedatatype
) returns table ...
WHERE someColumn = @.v
...
If that's the case, then the trigger could probably be written by
joining the inserted
table with whatever the current UDF applies its WHERE clause to, or with
not much more work than that.
In other words, as Ray said, what does the UDF (and the trigger) look like?
SK
Brent Black wrote:

>I've been able to do that in every case except where the ID value from the
>cursor is being passed into a udf that returns a table.. For example:
>insert into sometable (column1, column2)
> select distinct @.CursorValue, pgr.ID
> from someUDF(@.CursorValue) as pgr
>I tried changing this to:
>insert into sometable(column1, column2)
> select distinct i.ID, pgr.ID
> from someUDF(i.ID) as pgr,
> inserted i
> but that didn't work because it expects a single deterministic value to be
>passed into the UDL.. It appears that was why the original dev chose to us
e
>a cursor in the trigger to handle this in the first place. Any ideas on ho
w
>to do this without the cursor?
>Thanks!
>Brent Black
>Onvia.com
>Technical Lead/Database Administrator
>"Ray Higdon" <sqlhigdon@.nospam.yahoo.com> wrote in message
>news:OYCx3KL9DHA.2604@.TK2MSFTNGP10.phx.gbl...
>
>from
>
>to
>
>a
>
>
>|||Hi Brent,
Thank you for using the newsgroup.
Here is an example for your reference, you could run in your Query Analyzer:
use pubs
go
if exists (select * from dbo.sysobjects where id =
object_id(N'[dbo].[authorsx]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[authorsx]
GO
CREATE TABLE [dbo].[authorsx] (
[au_id] [id] NOT NULL ,
[au_lname] [varchar] (40) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[au_fname] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[phone] [char] (12) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[address] [varchar] (40) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[city] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[state] [char] (2) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[zip] [char] (5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[contract] [bit] NOT NULL ,
[test_column] varchar(2)
) ON [PRIMARY]
GO
if exists (select * from dbo.sysobjects where id =
object_id(N'[dbo].[author_fun]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[author_fun]
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
create function author_fun(@.state varchar(30))
returns table
as
return(select * from authors where @.state=authors.state
)
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
truncate table authorsx
insert into authorsx select *,1 from author_fun('CA')
select * from authorsx
go
drop table authorsx
So, I agree with Ray that if your the value returned by the UDF is match
the column you want to insert to or not.
Thanks.
Best regards
Baisong Wei
Microsoft Online Support
----
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
Please reply to newsgroups only. Thanks.|||Hi Brent,
I am reviewing you post and since I have not heard from you for some time,
I wonder whether you have solved you problem or you still have any
questions about that. For any questions, please feel free to post new
message here and I am glad to help.
Best regards
Baisong Wei
Microsoft Online Support
----
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
Please reply to newsgroups only. Thanks.

inserted table

Is it ever possible for the inserted table to have more than one row in a
for update trigger? One of our devs recently put a cursor in his for update
trigger to loop over rows in the inserted table. However, from what I
understand, inserted should never have more than one row in it. I just
wanted to verify this before I removed it as I am working on optimizing it.
Brent Black
Onvia.com
Technical Lead/Database AdministratorThis is a multi-part message in MIME format.
--=_NextPart_000_01FB_01C3F484.E84A26E0
Content-Type: text/plain;
charset="Windows-1252"
Content-Transfer-Encoding: 7bit
The inserted table can indeed have > 1 row in it and you code should take
this into account. Likely, you don't need a cursor either.
--
Tom
---
Thomas A. Moreau, BSc, PhD, MCSE, MCDBA
SQL Server MVP
Columnist, SQL Server Professional
Toronto, ON Canada
www.pinnaclepublishing.com/sql
"Brent Black" <bblack@.onvia.com> wrote in message
news:uhVRS4K9DHA.3404@.TK2MSFTNGP09.phx.gbl...
Is it ever possible for the inserted table to have more than one row in a
for update trigger? One of our devs recently put a cursor in his for update
trigger to loop over rows in the inserted table. However, from what I
understand, inserted should never have more than one row in it. I just
wanted to verify this before I removed it as I am working on optimizing it.
Brent Black
Onvia.com
Technical Lead/Database Administrator
--=_NextPart_000_01FB_01C3F484.E84A26E0
Content-Type: text/html;
charset="Windows-1252"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&

The inserted table can indeed have => 1 row in it and you code should take this into account. Likely, you don't =need a cursor either.
-- Tom
---T=homas A. Moreau, BSc, PhD, MCSE, MCDBASQL Server MVPColumnist, SQL =Server ProfessionalToronto, ON Canadahttp://www.pinnaclepublishing.com/sql">www.pinnaclepublishing.com=/sql
"Brent Black" wrote in =message news:uhVRS4K9DHA.3404=@.TK2MSFTNGP09.phx.gbl...Is it ever possible for the inserted table to have more than one row in =afor update trigger? One of our devs recently put a cursor in his for updatetrigger to loop over rows in the inserted table. =However, from what Iunderstand, inserted should never have more than one row in =it. I justwanted to verify this before I removed it as I am working on optimizing it.Brent BlackOnvia.comTechnical =Lead/Database Administrator

--=_NextPart_000_01FB_01C3F484.E84A26E0--|||Don't use a cursor in a trigger, typically people do something like this:
update table set column = value where prinmarykey = (select primary key from
inserted)
If you will have multiple updates or inserts you would want to change it to
this
update table set column = value where prinmarykey IN (select primary key
from inserted)
HTH
--
Ray Higdon MCSE, MCDBA, CCNA
--
"Brent Black" <bblack@.onvia.com> wrote in message
news:uhVRS4K9DHA.3404@.TK2MSFTNGP09.phx.gbl...
> Is it ever possible for the inserted table to have more than one row in a
> for update trigger? One of our devs recently put a cursor in his for
update
> trigger to loop over rows in the inserted table. However, from what I
> understand, inserted should never have more than one row in it. I just
> wanted to verify this before I removed it as I am working on optimizing
it.
> Brent Black
> Onvia.com
> Technical Lead/Database Administrator
>|||I've been able to do that in every case except where the ID value from the
cursor is being passed into a udf that returns a table.. For example:
insert into sometable (column1, column2)
select distinct @.CursorValue, pgr.ID
from someUDF(@.CursorValue) as pgr
I tried changing this to:
insert into sometable(column1, column2)
select distinct i.ID, pgr.ID
from someUDF(i.ID) as pgr,
inserted i
but that didn't work because it expects a single deterministic value to be
passed into the UDL.. It appears that was why the original dev chose to use
a cursor in the trigger to handle this in the first place. Any ideas on how
to do this without the cursor?
Thanks!
Brent Black
Onvia.com
Technical Lead/Database Administrator
"Ray Higdon" <sqlhigdon@.nospam.yahoo.com> wrote in message
news:OYCx3KL9DHA.2604@.TK2MSFTNGP10.phx.gbl...
> Don't use a cursor in a trigger, typically people do something like this:
> update table set column = value where prinmarykey = (select primary key
from
> inserted)
> If you will have multiple updates or inserts you would want to change it
to
> this
> update table set column = value where prinmarykey IN (select primary key
> from inserted)
> HTH
> --
> Ray Higdon MCSE, MCDBA, CCNA
> --
> "Brent Black" <bblack@.onvia.com> wrote in message
> news:uhVRS4K9DHA.3404@.TK2MSFTNGP09.phx.gbl...
> > Is it ever possible for the inserted table to have more than one row in
a
> > for update trigger? One of our devs recently put a cursor in his for
> update
> > trigger to loop over rows in the inserted table. However, from what I
> > understand, inserted should never have more than one row in it. I just
> > wanted to verify this before I removed it as I am working on optimizing
> it.
> >
> > Brent Black
> > Onvia.com
> > Technical Lead/Database Administrator
> >
> >
>|||What's the UDF look like?
--
Ray Higdon MCSE, MCDBA, CCNA
--
"Brent Black" <bblack@.onvia.com> wrote in message
news:ucGCsKN9DHA.1936@.TK2MSFTNGP12.phx.gbl...
> I've been able to do that in every case except where the ID value from the
> cursor is being passed into a udf that returns a table.. For example:
> insert into sometable (column1, column2)
> select distinct @.CursorValue, pgr.ID
> from someUDF(@.CursorValue) as pgr
> I tried changing this to:
> insert into sometable(column1, column2)
> select distinct i.ID, pgr.ID
> from someUDF(i.ID) as pgr,
> inserted i
> but that didn't work because it expects a single deterministic value to
be
> passed into the UDL.. It appears that was why the original dev chose to
use
> a cursor in the trigger to handle this in the first place. Any ideas on
how
> to do this without the cursor?
> Thanks!
> Brent Black
> Onvia.com
> Technical Lead/Database Administrator
> "Ray Higdon" <sqlhigdon@.nospam.yahoo.com> wrote in message
> news:OYCx3KL9DHA.2604@.TK2MSFTNGP10.phx.gbl...
> > Don't use a cursor in a trigger, typically people do something like
this:
> >
> > update table set column = value where prinmarykey = (select primary key
> from
> > inserted)
> >
> > If you will have multiple updates or inserts you would want to change it
> to
> > this
> >
> > update table set column = value where prinmarykey IN (select primary key
> > from inserted)
> >
> > HTH
> > --
> > Ray Higdon MCSE, MCDBA, CCNA
> > --
> > "Brent Black" <bblack@.onvia.com> wrote in message
> > news:uhVRS4K9DHA.3404@.TK2MSFTNGP09.phx.gbl...
> > > Is it ever possible for the inserted table to have more than one row
in
> a
> > > for update trigger? One of our devs recently put a cursor in his for
> > update
> > > trigger to loop over rows in the inserted table. However, from what I
> > > understand, inserted should never have more than one row in it. I
just
> > > wanted to verify this before I removed it as I am working on
optimizing
> > it.
> > >
> > > Brent Black
> > > Onvia.com
> > > Technical Lead/Database Administrator
> > >
> > >
> >
> >
>|||Brent,
I wouldn't be surprised if in this case the UDF is something like
create function someUDF(
@.v somedatatype
) returns table ...
WHERE someColumn = @.v
...
If that's the case, then the trigger could probably be written by
joining the inserted
table with whatever the current UDF applies its WHERE clause to, or with
not much more work than that.
In other words, as Ray said, what does the UDF (and the trigger) look like?
SK
Brent Black wrote:
>I've been able to do that in every case except where the ID value from the
>cursor is being passed into a udf that returns a table.. For example:
>insert into sometable (column1, column2)
> select distinct @.CursorValue, pgr.ID
> from someUDF(@.CursorValue) as pgr
>I tried changing this to:
>insert into sometable(column1, column2)
> select distinct i.ID, pgr.ID
> from someUDF(i.ID) as pgr,
> inserted i
> but that didn't work because it expects a single deterministic value to be
>passed into the UDL.. It appears that was why the original dev chose to use
>a cursor in the trigger to handle this in the first place. Any ideas on how
>to do this without the cursor?
>Thanks!
>Brent Black
>Onvia.com
>Technical Lead/Database Administrator
>"Ray Higdon" <sqlhigdon@.nospam.yahoo.com> wrote in message
>news:OYCx3KL9DHA.2604@.TK2MSFTNGP10.phx.gbl...
>
>>Don't use a cursor in a trigger, typically people do something like this:
>>update table set column = value where prinmarykey = (select primary key
>>
>from
>
>>inserted)
>>If you will have multiple updates or inserts you would want to change it
>>
>to
>
>>this
>>update table set column = value where prinmarykey IN (select primary key
>>from inserted)
>>HTH
>>--
>>Ray Higdon MCSE, MCDBA, CCNA
>>--
>>"Brent Black" <bblack@.onvia.com> wrote in message
>>news:uhVRS4K9DHA.3404@.TK2MSFTNGP09.phx.gbl...
>>
>>Is it ever possible for the inserted table to have more than one row in
>>
>a
>
>>for update trigger? One of our devs recently put a cursor in his for
>>
>>update
>>
>>trigger to loop over rows in the inserted table. However, from what I
>>understand, inserted should never have more than one row in it. I just
>>wanted to verify this before I removed it as I am working on optimizing
>>
>>it.
>>
>>Brent Black
>>Onvia.com
>>Technical Lead/Database Administrator
>>
>>
>>
>
>|||Hi Brent,
Thank you for using the newsgroup.
Here is an example for your reference, you could run in your Query Analyzer:
use pubs
go
if exists (select * from dbo.sysobjects where id =object_id(N'[dbo].[authorsx]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[authorsx]
GO
CREATE TABLE [dbo].[authorsx] (
[au_id] [id] NOT NULL ,
[au_lname] [varchar] (40) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[au_fname] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[phone] [char] (12) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[address] [varchar] (40) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[city] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[state] [char] (2) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[zip] [char] (5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[contract] [bit] NOT NULL ,
[test_column] varchar(2)
) ON [PRIMARY]
GO
if exists (select * from dbo.sysobjects where id =object_id(N'[dbo].[author_fun]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[author_fun]
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
create function author_fun(@.state varchar(30))
returns table
as
return(select * from authors where @.state=authors.state
)
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
truncate table authorsx
insert into authorsx select *,1 from author_fun('CA')
select * from authorsx
go
drop table authorsx
So, I agree with Ray that if your the value returned by the UDF is match
the column you want to insert to or not.
Thanks.
Best regards
Baisong Wei
Microsoft Online Support
----
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
Please reply to newsgroups only. Thanks.|||Hi Brent,
I am reviewing you post and since I have not heard from you for some time,
I wonder whether you have solved you problem or you still have any
questions about that. For any questions, please feel free to post new
message here and I am glad to help.
Best regards
Baisong Wei
Microsoft Online Support
----
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
Please reply to newsgroups only. Thanks.

Inserted row deletes after trigger

I'm hoping someone has seen this before because I have no idea what could be causing it.

I have an SQL 2005 database with multiple tables and several triggers on the various tables all set to run after insert and update.

My program inserts a record into the "items" via a SP that returns the index of the newly added row. The program then inserts a row into another table that is related to items. When the row is inserted into the second table it gets an error that it cannot insert the record because of a foreign key restraint. Checking the items table shows the record that was just inserted in there is now deleted.

The items record is only deleted when I have my trigger on that table enabled. Here is the text of the trigger:

GO
SETANSI_NULLSON
GO
SETQUOTED_IDENTIFIERON
GO

ALTERTRIGGER [dbo].[TestTrigger]
ON [dbo].[items]
AFTERINSERT

AS
BEGIN

SETNOCOUNTON;

INSERTINTO tblHistory(table_name, record_id, is_insert)
VALUES('items', 123, 1)

END

tblHistory's field types are (varchar(50), BigInt, bit).

As you can see there is nothing in the trigger to cause the items record to be deleted, so I have no idea what it could be? Anyone ever see this before?

Thanks in advance!

Hey,

I don't know that the row is deleted, but that the row doesn't get actually inserted for some reason. What do the two insertions look like? In SQL or ADO.NET code? Could it be that the first item doesn't get inserted, then returns a number that doesn't match an entry in that table, and that is why you get an error for the second insert?

|||

No, the first item is inserted and the returned value is exactly what it should be. When we test it without the trigger enabled and it all works, the new primary key value is the next value after the one that disapeared (i.e. if the record that was deleted was 5 the next one that works is 6).

|||

Are you using @.@.identity?

|||

If one of the follow on triggers fails, for whatever reason, the insert statement will be rolled back.

I suggest commenting out the triggers one by one (from last run to first run) until you figure out which one is the problem.

(Or learn to use the debugger in sql server.)

|||

David is correct in that the trigger code is considered part of the insert transaction.

If the trigger fails, then the entire "transaction" is rolled back, including the insert. If tblHistory has a foreign key constraint, and the trigger fails because of it, then you will get exactly what you are describing. The record is inserted partially (uncommitted), the trigger is fired, an error is encountered, then the insert is rolled back and the error from the trigger is sent to the client.

|||

It couldn't have been the trigger failing, b/c there are no constraints on the history table and while yo uare correct the error would have been returned as if it was coming from the insert statement I said above "When the row is inserted into the second table it gets an error that it cannot insert the record because of a foreign key restraint." The error was not about hte history table.

Motley you actually had the answer. What was happening is the stored procedure ran and inserted the row into items, the trigger ran on that and inserted the row into web updates, the stored procedure then returned the @.@.Identity, but since that returns the last identity of any insert to the database it was returning the identity of the history table, not the items table. When the second insert was run it was trying to insert the wrong identity and failed the foreign key restraint, resulting in the entire transaction to fail and rollback, giving the appearance the items record had been deleted.

Thanks for your help!

|||

Use scope_identity(), not identity! scope_identity was created to avoid just this problem!

sql

Wednesday, March 28, 2012

inserted and deleted table

hi

for after trigger the records stored in followig table

inserted and deleted table.

but i want to know where this tables physically stored ...i mean in which database master or some other database?

and 2nd thing tigger fired for each row or for only insert,delete,update statement?

thanx

Where stored?

Obviously in temp tables at tempdb.

Is it executed for each row?

No. If single query affects more than one row, the inserted or deleted table may have more than one row. When you write a trigger you have to keep consider this & you have to handle your trigger query which will support both single row & multiple rows.

|||

The table is not physically stored it is virtual only, it only exists within the trigger context. Triggers are fired per statement not per row, you will need to handle mutlirow existance in your trigger and in addition the occurence of no affected rows,a s the trigger is also fired if no rows is affected like

Code Snippet

UPDATE SomeTable SET SomeColumn = 'SomeValue' WHERE 1=2

Jens K. Suessmeyer

http://www.sqlserver2005.de

|||

Is it executed for each row?

No. If single query affects more than one row, the inserted or deleted table may have more than one row. When you write a trigger you have to keep consider this & you have to handle your trigger query which will support both single row & multiple rows.

mani

i mean trigger fired for each row or only for update statement..here i m not talking about inserted and deleted table

|||

On high level it is called virtual, but SQL Server always use the TempDB as workspace to store the data, so the data may be presented or stored in tempdb but you can't access these data from outside of your trigger scope & these are absolutely read-only.

There is interesting thread on same question on DB Engine forum

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=908238&SiteID=1

|||The answer is for one statement not for each rows.

|||thanx mani and jens.

inserted / deleted tables for triggers

Hi i was hoping someone could help me. If i have the following trigger
defined:
CREATE TRIGGER mytrigger ON mytableview
INSTEAD OF UPDATE
AS
UPDATE mytable SET
field1 = ISNULL(inserted.field1, 0),
field2 = ISNULL(inserted.field2, 0),
field3 = ISNULL(inserted.field3, 0)
FROM inserted
WHERE mytable.userid = inserted.userid
Iperform the following:
UPDATE mytableview
SET field1 = 1
WHERE userid = 1234
lets take for example the row pertaining to userid = 1234 within mytable to
be:
userid field1 field2 field3
1234 0 1 2
What is the state of the inserted table when the trigger is fired? Does the
inserted table do the following:
1) copy into itself the row from mytable pertaining to userid = 1234
2) modify this copied row to reflect field1 = 1
so inserted looks like this:
userid field1 field2 field3
1234 1 1 2
OR
1) creates a row within itself with field1 = 1, and all the other fields set
to NULL?
so inserted looks like this:
userid field1 field2 field3
NULL 1 NULL NULL
Ay help most appreciated. I think i am slightly with the state of
the inserted/deleted tables when triggers are invovled.
Cheers,
peterAn UPDATE with a trigger is performed as a DELETE followed by an INSERT. So
the DELETED table will contain the *before* data records and the INSERTED
table will contain the *after* data records.
HTH
Jerry
"PWalker" <pwalker@.nospam.com> wrote in message
news:OlU7ioz0FHA.2428@.tk2msftngp13.phx.gbl...
> Hi i was hoping someone could help me. If i have the following trigger
> defined:
> CREATE TRIGGER mytrigger ON mytableview
> INSTEAD OF UPDATE
> AS
> UPDATE mytable SET
> field1 = ISNULL(inserted.field1, 0),
> field2 = ISNULL(inserted.field2, 0),
> field3 = ISNULL(inserted.field3, 0)
> FROM inserted
> WHERE mytable.userid = inserted.userid
>
> Iperform the following:
>
> UPDATE mytableview
> SET field1 = 1
> WHERE userid = 1234
>
> lets take for example the row pertaining to userid = 1234 within mytable
> to be:
> userid field1 field2 field3
> 1234 0 1 2
> --
> What is the state of the inserted table when the trigger is fired? Does
> the inserted table do the following:
> 1) copy into itself the row from mytable pertaining to userid = 1234
> 2) modify this copied row to reflect field1 = 1
> so inserted looks like this:
> userid field1 field2 field3
> 1234 1 1 2
> OR
> 1) creates a row within itself with field1 = 1, and all the other fields
> set to NULL?
> so inserted looks like this:
> userid field1 field2 field3
> NULL 1 NULL NULL
>
> Ay help most appreciated. I think i am slightly with the state of
> the inserted/deleted tables when triggers are invovled.
> Cheers,
> peter
>|||thanks, so an update removes the relevant row(s) from the trigger table and
sticks them into the deleted table; then inserts the new modified row(s)
into both the trigger table and the inserted table.
thanks for the clarification.
cheers, peter

> An UPDATE with a trigger is performed as a DELETE followed by an INSERT.
> So the DELETED table will contain the *before* data records and the
> INSERTED table will contain the *after* data records.
> HTH
> Jerry
> "PWalker" <pwalker@.nospam.com> wrote in message
> news:OlU7ioz0FHA.2428@.tk2msftngp13.phx.gbl...
>

Inserted & Deleted Tables!

Suppose a trigger gets fired when the following UPDATE query gets
executed:
---
UPDATE Users SET Pwd='12345' WHERE UserID='jack' AND Pwd='11111'
---
Now the Inserted table will have the new record '12345' in the Pwd
column & the Deleted table will have the old record '11111' in the Pwd
column. So will the record 'jack' exist in the UserID column of both
the Inserted table & the Deleted table that the trigger will be making
use of?
Thanks,
ArpanHi
Yes, the whole row, as it was before and after are in the respective tables,
not just the column that changed.
If you update the primary key of a table, then comparing the Inserted and
Deleted becomes very difficult.
Regards
--
Mike Epprecht, Microsoft SQL Server MVP
Zurich, Switzerland
IM: mike@.epprecht.net
MVP Program: http://www.microsoft.com/mvp
Blog: http://www.msmvps.com/epprecht/
"Arpan" <arpan_de@.hotmail.com> wrote in message
news:1123800474.961292.259990@.g49g2000cwa.googlegroups.com...
> Suppose a trigger gets fired when the following UPDATE query gets
> executed:
> ---
> UPDATE Users SET Pwd='12345' WHERE UserID='jack' AND Pwd='11111'
> ---
> Now the Inserted table will have the new record '12345' in the Pwd
> column & the Deleted table will have the old record '11111' in the Pwd
> column. So will the record 'jack' exist in the UserID column of both
> the Inserted table & the Deleted table that the trigger will be making
> use of?
> Thanks,
> Arpan
>|||On 11 Aug 2005 15:47:55 -0700, Arpan wrote:

>Suppose a trigger gets fired when the following UPDATE query gets
>executed:
>---
>UPDATE Users SET Pwd='12345' WHERE UserID='jack' AND Pwd='11111'
>---
>Now the Inserted table will have the new record '12345' in the Pwd
>column & the Deleted table will have the old record '11111' in the Pwd
>column. So will the record 'jack' exist in the UserID column of both
>the Inserted table & the Deleted table that the trigger will be making
>use of?
Hi Arpan,
Almost.
The exact correct way to put this is:
- The deleted table will hold 0, 1, or many rows that all have UserID
'jack' and Pwd '11111'. Impossible to tell what the other columns will
be.
- The inserted table will hold 0, 1, or many rows (but the same number
as the deleted table) that all have UserID 'jack' and Pwd '12345'; the
other columns will be the same as in the corresponding rows in the
deleted table.
Best, Hugo
--
(Remove _NO_ and _SPAM_ to get my e-mail address)

insert/update trigger

Tbl1 inserts 1 record(with some fields populated) in tbl2. then I need get values from tbl3 to populate the rest of the fields in tbl2(update the record).
tbl1 = tblallBag_data
tbl2 = tblBag_data
tbl3 = tblShipping_sched

I created a trigger in tbl1 to insert a record into tbl2 and it works fine.

CREATE TRIGGER trgtblBag_Data ON dbo.tbltblallBag_data
FOR INSERT
AS

INSERT INTO tblBag_data (work_ord_num, work_ord_line_num, bag_num, bag_scanned_by, bag_date_scanned, bag_quantity)
SELECT work_ord_num, work_ord_line_num, bag_num, bag_scanned_by, bag_date_scanned, bag_quantity
FROM inserted

How can I update tbl2?
Should I create another trigger to update tbl2?
Should I join the two tbls(tbl2 & tbl3) to find
@.work_ord_num = work_ord_num , @.work_ord_line_num = work_ord_line_num

Thanks for your help!tbl2 and tbl3 should be joined with inserted.

Insert/Delete Trigger Misfires

I am having problems with a trigger that is designed to audit changes to a particular field in a table. If that field is updated, then the old record is inserted into an audit table.

This trigger never fails when I run test data against it from Query Analyzer. It works some of the time when the web application updates it, fails other times.

Typically, multiple records are updated at the same time. Any ideas?

Here is the Trigger:

create trigger t_u_product_rate_detail
on product_rate_detail
for insert, update, delete

as

/--Local variable
declare
@.auditdate datetime,
@.audituser sysname

--Set values so function isn't executed a bunch of times
select
@.auditdate = getdate(),
@.audituser = suser_sname()

if exists (select * from inserted)
begin
if exists (select * from deleted)
begin
insert into product_rate_detail_audit_log
select d.product_rate_detail_id,
d.product_rate_id,
d.day_of_week_id,
d.ad_size_id,
d.rate,
d.plan_vol,
d.plan_freq,
@.auditdate, @.audituser, 'U'
from deleted d
join inserted i on i.product_rate_detail_id = d.product_Rate_detail_id
where (d.rate <> 0 and d.rate is not null)
and i.rate <> d.rate -- this determines if the rate has changed.
end
end

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GOLots of stuff wrong with this. Heres some things to consider:
Your trigger is for insert/update/delete, but this criteria:if exists (select * from inserted)
begin
if exists (select * from deleted)
begin...will cause your insert statement to execute only on updates, because that is the only occasion when data exists in both inserted and deleted tables.
You really don't need to check for the existence of data in the inserted and deleted tables anyway. If you reference them as a source of data in a statement and they are empty, then your statement will just not do anything. So drop the "if exists" clauses completely.
If you just want to capture updates and deletes then you need only reference the deleted table. The inserted table contains the new values, and looks like you are not archiving those (until they themselves are updated).
You can also drop the @.AuditDate and @.AuditUser variables, and just reference getdate() and suser_sname() directly in your update statement. suser_sname() is constant throughout the transaction, and unless you have a truly massive update then getdate() will return a consistent value across all affected records as well.
Dropping your exists clauses and your unnecessary variable declarations will simplify your code, and simpler is always better.|||Well, let me bite ...

First, check for existence is always a good idea, simply because attempting to perform an operation on an empty set also has its cost and contributes to resource contention. Besides the trigger will get fired even if 0 rows are updated.

Second, if you all want to use best practices, - do not perform mass updates, so that the trigger does not have to kill the server while processing millions of rows. Also, (and this is truly the best practice point) - read your virtual tables only once, because this opration in itself is extremely expensive. In order to satisfy this requirement, - select * into #tmp from deleted!

Third, - remove references to INSERT and DELETE in the trigger definition. UPDATE occurs only when a record is updated, not when it is deleted or inserted (unless your app performs UPDATE by issueing DELETE+INSERT).

Friday, March 23, 2012

INSERT UPDATE Trigger Question

How would I write a trigger that updates the values of a Description
column to upper case for even IDs and to lower case for odd IDs? I
need this trigger to fire for INSERT and UPDATE events.Hi

Try something like:

CREATE TABLE Test ( id int not null identity (1,1), Description char(10) )

CREATE TRIGGER Test_Insert ON Test FOR INSERT AS
UPDATE TEST SET Description = CASE Id%2 WHEN 0 THEN UPPER(Description) ELSE
LOWER (Description) END

INSERT INTO TEST ( Description ) VALUES ('One')
INSERT INTO TEST ( Description ) VALUES ('Two')
INSERT INTO TEST ( Description ) VALUES ('Three')
INSERT INTO TEST ( Description ) VALUES ('four')
INSERT INTO TEST ( Description ) VALUES ('five')
INSERT INTO TEST ( Description ) VALUES ('SIX')
INSERT INTO TEST ( Description ) VALUES ('SEVEN')

SELECT * from Test

John

<imani_technology@.yahoo.com> wrote in message
news:f9208446.0309011615.5f269625@.posting.google.c om...
> How would I write a trigger that updates the values of a Description
> column to upper case for even IDs and to lower case for odd IDs? I
> need this trigger to fire for INSERT and UPDATE events.|||imani_technology@.yahoo.com wrote in message news:<f9208446.0309011615.5f269625@.posting.google.com>...
> How would I write a trigger that updates the values of a Description
> column to upper case for even IDs and to lower case for odd IDs? I
> need this trigger to fire for INSERT and UPDATE events.

You might want to consider formatting the text on the client, when you
retrieve it from the database - presentation tasks don't really belong
in a database. But if you want to do it using a trigger, something
like this should work (assuming your 'ID' is an integer key column):

create trigger ATR_UI_MyTable
on dbo.MyTable after insert, update
as
update dbo.MyTable
set DescriptionColumn =
case i.IDColumn % 2
when 1 then lower(i.DescriptionColumn)
when 0 then upper(i.DescriptionColumn)
end
from dbo.MyTable t
join inserted i
on t.IDColumn = i.IDColumn

Simon

Insert Triggers

I have written an Insert Trigger to examine newly inserted records and set some values. However, each time a record is inserted, all records are checked. How can I make the trigger work only on newly inserted records?Within the trigger, you can access a view called INSERTED that shows only the rows that are being inserted by the statement that launched the trigger. You can use the INSERTED view (probably via a JOIN) to limit the number of rows you are affecting in your underlying table.

-PatP|||my telepathic usb port is clogged...can you post the trigger...

probably take us a few minutes...

DDL would be nice as well

and pat's correct(what again? say it ain't so...)|||CREATE TRIGGER CheckWorkflow ON [dbo].[tblGroup]
FOR INSERT
AS
insert into WFTasks (DataRecordId, TaskNum, Status, UserId, StartDateTime)
select tblGroup.Id as DataRecordId,
1 as TaskNum,
"Ready" as Status,
tblUsers.Id as UserId,
getdate() as StartDateTime
from tblGroup, tblUsers, tblVendors where (tblGroup.I_Field3=tblVendors.OdissVendorId)
And (tblGroup.I_Field6 Is Null OR tblGroup.I_Field6='0')
And (tblUsers.WFID=1)

..a little complex. the check for tblGroup.I_Field6 is necessitated because all records are being checked - this where clause could be stripped off if only new records were being checked.|||Something like this would do it:

CREATE TRIGGER CheckWorkflow ON [dbo].[tblGroup]
FOR INSERT
AS
if exists (select 1 from inserted)
insert into WFTasks (DataRecordId, TaskNum, Status, UserId, StartDateTime)
select i.Id, 1, 'Ready', u.Id, getdate()
from inserted i
inner join tblVendors v
on i.I_Field3=v.OdissVendorId
inner join tblUsers u
on (u.WFID=1)|||thanx..will try this.

Insert Trigger with If Statement

I want to check if a field has a 0 in it, if it does it should run some
code, if not do nothing
If field1 = 0 then
some code
end if
Please advise of the syntax for this
TIA PaulTry something on these lines:
If Exists (Select 1 from <Table> where field = 0)
Begin
-- the activity you wanted to do
End
HTH,
Vinod Kumar
MCSE, DBA, MCAD, MCSD
http://www.extremeexperts.com
http://groups.msn.com/SQLBang
Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp
"Paul Goldney" <paulg@.wizardit.co.uk> wrote in message
news:ca97dk$pm3$1$8302bc10@.news.demon.co.uk...
> I want to check if a field has a 0 in it, if it does it should run some
> code, if not do nothing
> If field1 = 0 then
> some code
> end if
> Please advise of the syntax for this
> TIA Paul
>|||Remember that more than one row may be inserted at once. Maybe one row = 0
and another row is <> 0. Probably you just need a WHERE clause on whatever
statement(s) are in "some code" instead of an IF statement:
?
..
FROM Inserted WHERE col = 0
You can test for col = 0 in an IF statement using EXISTS but crucially this
tests for the presence of *any* row where col = 0, which may or may not be
what you want in your trigger.
IF EXISTS
(SELECT *
FROM Inserted
WHERE col = 0)
David Portas
SQL Server MVP
--

Insert Trigger with If Statement

I want to check if a field has a 0 in it, if it does it should run some
code, if not do nothing
If field1 = 0 then
some code
end if
Please advise of the syntax for this
TIA Paul
Try something on these lines:
If Exists (Select 1 from <Table> where field = 0)
Begin
-- the activity you wanted to do
End
HTH,
Vinod Kumar
MCSE, DBA, MCAD, MCSD
http://www.extremeexperts.com
http://groups.msn.com/SQLBang
Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
"Paul Goldney" <paulg@.wizardit.co.uk> wrote in message
news:ca97dk$pm3$1$8302bc10@.news.demon.co.uk...
> I want to check if a field has a 0 in it, if it does it should run some
> code, if not do nothing
> If field1 = 0 then
> some code
> end if
> Please advise of the syntax for this
> TIA Paul
>
|||Remember that more than one row may be inserted at once. Maybe one row = 0
and another row is <> 0. Probably you just need a WHERE clause on whatever
statement(s) are in "some code" instead of an IF statement:
?
...
FROM Inserted WHERE col = 0
You can test for col = 0 in an IF statement using EXISTS but crucially this
tests for the presence of *any* row where col = 0, which may or may not be
what you want in your trigger.
IF EXISTS
(SELECT *
FROM Inserted
WHERE col = 0)
David Portas
SQL Server MVP

Insert Trigger with If Statement

I want to check if a field has a 0 in it, if it does it should run some
code, if not do nothing
If field1 = 0 then
some code
end if
Please advise of the syntax for this
TIA PaulTry something on these lines:
If Exists (Select 1 from <Table> where field = 0)
Begin
-- the activity you wanted to do
End
--
HTH,
Vinod Kumar
MCSE, DBA, MCAD, MCSD
http://www.extremeexperts.com
http://groups.msn.com/SQLBang
Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinfo/productdoc/2000/books.asp
"Paul Goldney" <paulg@.wizardit.co.uk> wrote in message
news:ca97dk$pm3$1$8302bc10@.news.demon.co.uk...
> I want to check if a field has a 0 in it, if it does it should run some
> code, if not do nothing
> If field1 = 0 then
> some code
> end if
> Please advise of the syntax for this
> TIA Paul
>|||Remember that more than one row may be inserted at once. Maybe one row = 0
and another row is <> 0. Probably you just need a WHERE clause on whatever
statement(s) are in "some code" instead of an IF statement:
?
...
FROM Inserted WHERE col = 0
You can test for col = 0 in an IF statement using EXISTS but crucially this
tests for the presence of *any* row where col = 0, which may or may not be
what you want in your trigger.
IF EXISTS
(SELECT *
FROM Inserted
WHERE col = 0)
--
David Portas
SQL Server MVP
--sql

Insert Trigger Using Variables Help

Can somebody please help me with compiling my insert trigger below. I am fairly new to SQL server 2000 and I am having troubles with using variables in insert triggers. The trigger that I am creating will basically update another table based on a certain criteria that is not specified below. I am hoping to first get my trigger to work then apply the criteria on when to fire afterwards. I just need help with being able to store values in my declared variables for insert into another table. Thanks in advance for everyones help.

Use database_testing

IF EXISTS (SELECT name FROM sysobjects
WHERE type = 'TR' AND name = 'Trigger_Name')
DROP TRIGGER Trigger_Name
GO

CREATE TRIGGER Trigger_Name
ON [trigger_table] FOR INSERT
AS
Declare @.resource_id int = inserted.resource
@.type = varchar(100) = inserted.type
@.date_logged (datetime) = inserted.creation_date
@.created varchar(100) = inserted.username

Insert into table_A (resource_id, resource_type, date_created, created_by)
values (resource_id,type, date_logged, created)You didn't specified that exactly what you want to fulfill. I think you want to track users for insert row or update row.

CREATE TRIGGER Trigger_Name
ON [trigger_table] FOR INSERT
AS

SET NOCOUNT ON

Begin
Insert into table_A (resource_id, resource_type, date_created, created_by)
SELECT inserted.resource
inserted.type,
inserted.creation_date,
inserted.username
FROM inserted
End

SET NOCOUNT OFF|||rajeshpatel gave you probably the nicest sollution. If you want to hold on to your own script for some reason, I filtered some errors out of it. This is what it should look like:

CREATE TRIGGER Trigger_Name
ON [trigger_table] FOR INSERT
AS
BEGIN
Declare @.resource_id int
, @.type varchar(100)
, @.date_logged datetime
, @.created varchar(100)

select @.resource_id = inserted.resource
, @.type = inserted.type
, @.date_logged = inserted.creation_date
, @.created = inserted.username

Insert into table_A
(resource_id, resource_type, date_created, created_by)
values
(@.resource_id,@.type, @.date_logged, @.created)
...
END

Gr,
Yveau

Insert Trigger to Update table

Hi,

Does anyone know of a simple way to do this? I want to create an
insert trigger for a table and if the record already exists based on
some criteria, I want to update the table with the values that are
passed in via the insert trigger without having to use all the 'set'
statements for each field (so if we add fields in the future I won't
have to update the trigger). In other words, I want the trigger code
to look something like this:

if exists (select * from TableA where Fld1 = inserted.Fld1) then
//don't do insert, do an update instead (would i want to rollback here?
and will I have access to the 'inserted' table still?)
Update TableA
Set TableA.<all the fields> = Inserted.<all the fields>
where Fld1 = inserted.Fld1
end if

Any help or ideas would be appreciated.
Thanks,
TeresaUPDATE requires that you specify the columns by name. It's best
practice to do so in an INSERT statement too.

Always specify the column names. In the long run this will improve
reliability and save you development time.

--
David Portas
SQL Server MVP
--|||takilroy@.yahoo.com wrote:

> Hi,
> Does anyone know of a simple way to do this? I want to create an
> insert trigger for a table and if the record already exists based on
> some criteria, I want to update the table with the values that are
> passed in via the insert trigger without having to use all the 'set'
> statements for each field (so if we add fields in the future I won't
> have to update the trigger). In other words, I want the trigger code
> to look something like this:
> if exists (select * from TableA where Fld1 = inserted.Fld1) then
> //don't do insert, do an update instead (would i want to rollback here?
> and will I have access to the 'inserted' table still?)
> Update TableA
> Set TableA.<all the fields> = Inserted.<all the fields>
> where Fld1 = inserted.Fld1
> end if
> Any help or ideas would be appreciated.
> Thanks,
> Teresa

Nice hack.

A rollback is no good because you'd lose the update as well. But you could
delete the inserted row.

You may also have issues with primary keys and other constraints. If a
constraint fires before the trigger, your insert will fail on a pk
constraint and your clever trigger will never fire.

Finally, the performance issue is real. Doing the insert, deleting it, and
then updating causes only one real write to the table that has to be
committed, but carries three complete journal writes. An update only
carries two discreet write. It might be worthwhile to pump a few million
operations in each combination so you can at least speak knowledgeably
about what the real performance price is.

--
Kenneth Downs
Secure Data Software, Inc.
(Ken)nneth@.(Sec)ure(Dat)a(.com)|||On 12 May 2005 08:50:10 -0700, takilroy@.yahoo.com wrote:

>Hi,
>Does anyone know of a simple way to do this? I want to create an
>insert trigger for a table and if the record already exists based on
>some criteria, I want to update the table with the values that are
>passed in via the insert trigger without having to use all the 'set'
>statements for each field (so if we add fields in the future I won't
>have to update the trigger). In other words, I want the trigger code
>to look something like this:
>if exists (select * from TableA where Fld1 = inserted.Fld1) then
>//don't do insert, do an update instead (would i want to rollback here?
>and will I have access to the 'inserted' table still?)
> Update TableA
> Set TableA.<all the fields> = Inserted.<all the fields>
> where Fld1 = inserted.Fld1
>end if
>Any help or ideas would be appreciated.
>Thanks,
>Teresa

Hi Teresa,

There is no way to avoid listing the columns in an UPDATE statement. If
there were, I'd recommend against it (just as I recommend against using
SELECT * or INSERT without column-list in production code).

Also, your trigger's pseudo-code will do an update for all rows that
were inserted if at least one of them exists in TableA. You could remove
the existance check; the effect will be the same (rows that are not in
TableA won't be changed, rows that are will be - and if no row in
inserted is also in TableA, nothing changes in TableA), but it will
somewhat improve performance.

Also, Kenneth is correct - constraints are checked before the trigger is
executed. The only way around that is to use an INSTEAD OF trigger that
updates rows that are already present and inserts rows that are not yet
present.

If you need help transforming this to an INSTEAD OF trigger, just
holler.

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)

Insert trigger to populate other columns in same row

I'm looking for an efficient way to populate derived columns when I
insert data into a table in SQL Server. In Informix and PostgreSQL
this is easily done using the "for each row..." syntax, but all I've
been able to come up with for SQL Server is the following:

create table testtrigger(id integer unique, b integer, c integer)
go

create trigger testtrigger_ins on testtrigger
for insert as
update testtrigger set c = (select ...some_function_of_b... from
testtrigger t1,inserted t2
where t1.id = t2.id)
where id in (select id from inserted);
go

where id is testrigger's unique id field, and c is a field derived from
b.

This seems terribly inefficient since each insert results in an extra
select and update. And if the table is large and unindexed (which it
could be if we are bulk loading) then I would imagine this would be
very slow.

Are there any better ways of doing this?

Many thanks,...
Mike Dunham-WilkieCREATE table ><>>Look at computered columns is your answer . BTW no
data is stored for this type of column.

e.g. CREATE TABLE mytable
(
low int,
high int,
myavg AS (low + high)/2

Duncan|||On 22 Sep 2006 13:11:12 -0700, mike@.barrodale.com wrote:

Quote:

Originally Posted by

>I'm looking for an efficient way to populate derived columns when I
>insert data into a table in SQL Server. In Informix and PostgreSQL
>this is easily done using the "for each row..." syntax, but all I've
>been able to come up with for SQL Server is the following:


(snip)

Quote:

Originally Posted by

>This seems terribly inefficient since each insert results in an extra
>select and update. And if the table is large and unindexed (which it
>could be if we are bulk loading) then I would imagine this would be
>very slow.
>
>Are there any better ways of doing this?


Hi Mike,

Since SQL Server is optimized for set-based operations, you'll probably
find the speed of these operations to be quite adequate in most cases.

Here's an alternate syntax of the UPDATE statement that might result in
even faster operation. Note, though, that this syntax has some quirks,
especially if there's not a guaranteed one to one mapping of rows in the
update target and the source of the data.

UPDATE t
SET c = some_function_of_b
FROM testtrigger AS t
INNER JOIN inserted AS i
ON i.id = t.id

But only use this if you have a solid reason for being unable to use a
computed column, as Duncan ("undercups") demonstrates in his reply!

--
Hugo Kornelis, SQL Server MVP

Insert Trigger sometimes not firing

hi all

i have an issue with an insert trigger sometimes not firing.

here is the trigger

CREATE TRIGGER Insert_tPABillToAddr ON [dbo].[tPA00175]
FOR INSERT
AS

INSERT into tPABillToAddr
(
chrJobNumber
)

SELECT chrJobNumber
FROM inserted

when the user enters a new this table is to insert one column into another table. the thing is, sometimes it does not do the insert. any ideas as to why? it is a very uncommon thing, lets say once out of every 20 inserts does it fail. but it is crucial that it never fails.

thanksYou can be sure the trigger is firing.
Are you sure the insert is occurring? Add a few more lines to the trigger so that data is also inserted into a log table indicating the datetime, login, and chrJobNumber of each insert.
Keep in mind that your trigger will not fire for updates that may modify an existing chrJobNumber value.|||what would be a probable cause for it not to fire? this is just an insert...i have no updates associated with it.|||While I've investigated a few cases where people thought that triggers didn't fire, I've only seen one or two cases in SQL 4.2 and SQL 6.0 where there were actually cases where a trigger should have fired, but didn't. Those were bugs in the database engine itself.

I haven't seen that happen since the release of SQL 6.5.

-PatP|||what if you have more than 1 insert trigger...lets say the other, for whatever reason doesnt fire, does it cause this one to cease as well?

Insert Trigger Question

Can someone help me with this scenario:
I have 2 tables one detail and one summary. The key fields for betwen the the detail and summary tables are the date field na the part # field.
I need to create a trigger that will insert records when they do not exist in the summary table and also only update the records that are needing to be modified. Any Ideas?

ThanksReal time warehousing?

Can't you run a scheduled process instead?|||Originally posted by Brett Kaiser
Real time warehousing?

Can't you run a scheduled process instead?

I need to have this summary infomration available at any time the daily reports need to be run. A scheduled process would be easier but I need to keep this table up to date as transcations are processed in the detail table.|||Use this as an example:

create table item(id int identity,item# varchar(10))
create table itemsummary(id int identity,item# varchar(10),quantity int)
go
create trigger iu_item on item
for insert,update
as
insert itemsummary(item#)
select item# from inserted i
where not exists(select 1 from itemsummary where item#=i.item#)
update itemsummary set quantity=(select count(*) from item i where i.item#=itemsummary.item#)
go
insert item(item#) values('#1')
insert item(item#) values('#1')
insert item(item#) values('#2')

select * from item
select * from itemsummary|||He'll need to update..the count? for the part#

So you need 2 sections...

Check

-- An Update
IF EXISTS (SELECT * FROM inserted) AND EXISTS (SELECT * FROM deleted)

--An INSERT
IF EXISTS (SELECT * FROM inserted) AND NOT EXISTS (SELECT * FROM deleted)

Then do your apporpriate action...

What's the transaction level?sql