Trigger insert old values- values that was updated - sql

I need to create trigger in SQL Server 2008 that gone insert all values from one row in which some value was changed into Log table!
For example if i have table Employees that have column id, name , password, and i update this table and insert new value for column name, than i need to insert values that was in table Employees after update in table Log.
How I can do this? Thanks!

In your trigger, you have two pseudo-tables available, Inserted and Deleted, which contain those values.
In the case of an UPDATE, the Deleted table will contain the old values, while the Inserted table contains the new values.
So if you want to log the ID, OldValue, NewValue in your trigger, you'd need to write something like:
CREATE TRIGGER trgEmployeeUpdate
ON dbo.Employees AFTER UPDATE
AS
INSERT INTO dbo.LogTable(ID, OldValue, NewValue)
SELECT i.ID, d.Name, i.Name
FROM Inserted i
INNER JOIN Deleted d ON i.ID = d.ID
Basically, you join the Inserted and Deleted pseudo-tables, grab the ID (which is the same, I presume, in both cases), the old value from the Deleted table, the new value from the Inserted table, and you store everything in the LogTable

Here's an example update trigger:
create table Employees (id int identity, Name varchar(50), Password varchar(50))
create table Log (id int identity, EmployeeId int, LogDate datetime,
OldName varchar(50))
go
create trigger Employees_Trigger_Update on Employees
after update
as
insert into Log (EmployeeId, LogDate, OldName)
select id, getdate(), name
from deleted
go
insert into Employees (Name, Password) values ('Zaphoid', '6')
insert into Employees (Name, Password) values ('Beeblebox', '7')
update Employees set Name = 'Ford' where id = 1
select * from Log
This will print:
id EmployeeId LogDate OldName
1 1 2010-07-05 20:11:54.127 Zaphoid

In SQL Server 2008 you can use Change Data Capture for this. Details of how to set it up on a table are here http://msdn.microsoft.com/en-us/library/cc627369.aspx

createTRIGGER [dbo].[Table] ON [dbo].[table]
FOR UPDATE
AS
declare #empid int;
declare #empname varchar(100);
declare #empsal decimal(10,2);
declare #audit_action varchar(100);
declare #old_v varchar(100)
select #empid=i.Col_Name1 from inserted i;
select #empname=i.Col_Name2 from inserted i;
select #empsal=i.Col_Name2 from inserted i;
select #old_v=d.Col_Name from deleted d
if update(Col_Name1)
set #audit_action='Updated Record -- After Update Trigger.';
if update(Col_Name2)
set #audit_action='Updated Record -- After Update Trigger.';
insert into Employee_Test_Audit1(Col_name1,Col_name2,Col_name3,Col_name4,Col_name5,Col_name6(Old_values))
values(#empid,#empname,#empsal,#audit_action,getdate(),#old_v);
PRINT '----AFTER UPDATE Trigger fired-----.'

ALTER trigger ETU on Employee FOR UPDATE
AS
insert into Log (EmployeeId, LogDate, OldName)
select EmployeeId, getdate(), name
from deleted
go

Related

How to get old value and new value of multiple field in trigger in SQL server?

I have a table Person:
CREATE TABLE Person
(
ID INT PRIMARY KEY,
FirstName varchar(50),
LastName varchar(50),
Phone varchar(50),
Address varchar(50),
City varchar(50),
PinCode varchar(50),
DateOfBirth DATETIME,
UpdatedOn DATETIME,
UpdatedBy varchar(50)
)
Whenever I insert or update the multiple fields from above table then I want previous value and current value of all updated fields and store that in another table using Trigger. How we can get values of all updated fields.
For example
INSERT INTO Person
VALUES (1, 'first', 'last', '11111', 'add', 'city', 'pin', GETDATE(), GETDATE(), 'ABC')
UPDATE Person
SET FirstName = 'First11',
LastName = 'Last22',
Phone = '1010101010'
WHERE id = 1
When I will hit above commands in both cases I want old and current value and store it in another table. How we can achieve this using triggers?
For SQL Server when you updated ( he delete the old values and then insert the new values )
ALTER TRIGGER [dbo].[YOUR_TRIGGER_NAME_INSERT]
ON [dbo].[YOUR_TABLE]
AFTER INSERT --Here when you insered rows
AS
BEGIN
select * from inserted --get all inserted rows
--Your code
END
And Update
ALTER TRIGGER [dbo].[YOUR_TRIGGER_NAME_UPDATE]
ON [dbo].[YOUR_TABLE]
AFTER UPDATE--Here when you updated rows
AS
BEGIN
select * from inserted --get all inserted (new values) rows
select * from deleted--get all deleted (old values) rows
--Your code
END

SQL Inserted table trigger

If I run the following select statement inside an insert trigger, is it possible that it will return more than one result?:
DECLARE #variable char(1) = (SELECT ID FROM inserted)
If so, then what's the best to handle it?
Here is the problem that I am trying to solve: Every time when the new record is inserted into a table, I want to take the newly inserted ID and insert it into another table(if it doesn't exists).
Thank you!
Instead of
DECLARE #variable char(1) = (SELECT ID FROM inserted)
You can do something like following:
Declare #VarTempTbl as table (id int)
Insert into #VarTempTbl (id)
Select id from inserted
So that you can get those values for further processing
Now, I had created Two tables One for Master table and another for When any Insertion happens in that Master table, that entry has to inserted into the another table.
CREATE TABLE tblEmployee
(
Id int Primary Key,
Name nvarchar(30),
Gender nvarchar(10),
DepartmentId int
)
CREATE TABLE tblEmployee_New
(
Id int Primary Key,
Name nvarchar(30),
Gender nvarchar(10),
DepartmentId int
)
Trigger:
CREATE TRIGGER TR_EMPLOYEEDETAILS_AFTEROFINSERT
ON TBLEMPLOYEE
AFTER INSERT
AS
BEGIN
TRUNCATE TABLE tblEmployee_New
INSERT INTO TBLEMPLOYEE_NEW(ID, NAME, GENDER, DEPARTMENTID)
SELECT ID, NAME, GENDER, DEPARTMENTID
FROM INSERTED
END
Now Lets try to insert into record into a master table
Insert into tblEmployee values (1,'John', 'Male', 3)
Insert into tblEmployee values (2,'Mike', 'Male', 2)
It has automatically insert the newly inserted records into the another table.
If your want to remove the Previous records then add a drop Statement in that above Trigger.
Note: You can also use #Temp Table instead of creating a another table('tblEmployee_New')
Kinldy Share your comments

Insert in to 2 tables from 2 tables from a different database

I am trying to read data from 2 tables and inserting to similar tables in a different database.
Here is my query
BEGIN TRANSACTION
Delete from aspnet_Website.[dbo].[Places]
DECLARE #AutoID int;
insert into aspnet_Website.[dbo].[Places] (ReferenceID, Name, OtherKnownNames, Description, Email)
select ReferenceID, Name, OtherKnownNames, Description, Email from DB_A290D0_places.
[dbo].[places]
where PublishingStatus=0
SELECT #AutoID = scope_identity();
insert into aspnet_Website.[dbo].[Schedules] (Timing, Type, PlaceID)
select [Timing], [Type], #AutoID from DB_A290D0_places.[dbo].[Schedules]
COMMIT
I am getting error
Incorrect syntax near '#AutoID'.
and even I am not sure that it will work or not.
'Places' table has ID field which is auto id and it is used as FK in Schedule table, so for every 'place' row I need to get auto id and insert it into the schedule table along with the corresponding table data from another database.
Update1 : I have fixed the syntax error, I can see records added into the table but last generated AutoID is being used for all rows in child table. I want to use autoid generated for each row.
Update2 : following script worked
BEGIN TRANSACTION
Delete from aspnet_Website.[dbo].[Places]
declare #NewId table (ID int);
insert into aspnet_Website.[dbo].[Places] (ReferenceID, Name, OtherKnownNames, Description, Email)
select ReferenceID, Name, OtherKnownNames, Description, Email from DB_A290D0_places.
[dbo].[places]
where PublishingStatus=0
output Inserted.ID into #NewId (ID)
insert into aspnet_Website.[dbo].[Schedules] (Timing, [Type], PlaceID)
select [Timing], [Type], P.ID
from DB_A290D0_places.[dbo].[Schedules] S
inner join #NewId P on P.ID = S.PlaceId;
COMMIT
You can't store more than one value in a variable, the the line SELECT #AutoID = scope_identity(); will only capture the last id inserted.
To solve you problem have you considered not changing the ids by setting IDENTITY_INSERT ON and inserting the original ids?
Otherwise use the OUTPUT clause to capture the new ids, map them to the old ids, and then insert them into the Schedules table.
begin transaction
delete from aspnet_Website.[dbo].[Places];
declare #AutoID int;
declare #NewId table (ID int, OldID int);
-- In an insert statement you can't access the source table in the output clause unfortunately
/*
insert into aspnet_Website.[dbo].[Places] (ReferenceID, [Name], OtherKnownNames, [Description], Email)
output Inserted.ID, P.ID into #NewId (ID, OldID)
select ReferenceID, [Name], OtherKnownNames, [Description], Email
from DB_A290D0_places.[dbo].[places] P
where PublishingStatus = 0;
*/
-- However in a merge statement you can access both the source and destination tables in the output clause.
merge into aspnet_Website.[dbo].[Places] T
using DB_A290D0_places.[dbo].[places] S on 1 = 0 -- always false
when not matched by target and S.PublishingStatus = 0 then -- happens for every row, because 1 is never 0
insert (ReferenceID, [Name], OtherKnownNames, [Description], Email)
values (S.ReferenceID, S.[Name], S.OtherKnownNames, S.[Description], S.Email)
output Inserted.ID, S.ID into into #NewId (ID, OldID);
insert into aspnet_Website.[dbo].[Schedules] (Timing, [Type], PlaceID)
select [Timing], [Type], P.ID
from DB_A290D0_places.[dbo].[Schedules] S
inner join #NewId P on P.OldId = S.PlaceId;
commit

how to create trigger on table after insert to add Row in Audit table

i want to Create a trigger on student table after insert to add Row in Student Audit table (Server User Name , Date, Note) where note will be “[username] Insert New Row with Key=[Key Value] in table student
create trigger t1 on Student
after insert
as
declare #x int
begin
insert into Audit
(ServerUserName, Date, Note)
select SUSER_SNAME(), getdate(),SUSER_SNAME()+'Insert New Row with Key'+#x+'in Student '
from Student t
end
go
how can i do this with #x that's i mean #x is equal key
Firstly, remove declare #x int line. You can't pass parameters to trigger. If you want to get inserted row, you can select it as inserted like this;
create trigger t1 on Student
after insert
as
begin
insert into Audit
(ServerUserName, Date, Note)
select SUSER_SNAME(), getdate(),SUSER_SNAME()+'Insert New Row with Key'+cast(t.Id as nvarchar(10))+'in Student '
from Student t where Id IN (select Id from inserted)
end
go

Insert New data into multiple tables with Foreign Key simultaneously in One query in sql server

I have two tables:
tblDepartment:
Id Name
and
tblEmployee:
Id FullName Dept_ID
Dept_ID is a foreign key for tblDepartment
I want to insert a new record into both tables.
I tried this:
declare #id int
insert dbo.tblDepartment
select Name='Name1'
select id = scope_Identity()
insert dbo.tblEmployee
select FullName = 'Name1'
select Dept_Id=#id
select Id=#id
However, this is not working. I searched through other posts, but they contain solutions for inserting existing data from one table into another, not creating a new record. How can I do this in one query?
You need to use variables properly along with column lists for inserts. Assuming you are using SQL Server:
declare #id int ;
insert dbo.tblDepartment(Name)
select 'Name1';
select #id = scope_Identity();
insert dbo.tblEmployee(FullName, Dept_Id)
select 'Name1', #id;
Also, scope_identity() is okay for learning about such id's. The safe way to really get this information is to use the output clause.
declare #id int
insert dbo.tblDepartment(Name)
select 'Name1'
-- Don't insert any other statements before next line...
select #id=scope_Identity()
insert dbo.tblEmployee(Fullname, Dept_ID)
select 'Name1', #id