Sql Triggers-Implementation Issue

Multi tool use
Multi tool use


Sql Triggers-Implementation Issue



Hi guys i am making 2 tables for implementing triggers--


create table emp(id int primary key identity(1,1),
name char(40),
salary varchar(50),
gender char(40),
departmentid int);

insert into emp(name,salary,gender,departmentid) values ('jimmi',4800,'Male',4);

create table emp_audit
(
id int primary key identity(1,1),
audit varchar(60)
);
alter trigger trigger_em_update on emp for update
as begin
Declare @Id int
Declare @oldname char(40),@newname char(40)
Declare @oldsal int,@newsal int
Declare @oldgen char(40),@newgen char(40)
Declare @olddeptid int,@newdeptid int

Declare @auditstring nvarchar(max)


--select * from deleted;

select * into #temptable from inserted;

while(Exists(select id from #temptable)) --boolean condition if there are rows are not
Begin
set @auditstring =''

--if there are many rows we still select the first one

select Top 1 @Id =id,@newname=name,@newgen=gender,@newsal=salary,@newdeptid=departmentid
from #temptable;

select Top 1 @Id =id,@oldname=name,@oldgen=gender,@oldsal=salary,@olddeptid=departmentid
from deleted where @Id=id;

set @auditstring=' Employee with id= '+CAST(@Id as varchar(20))+ ' changed '
if(@oldname<>@newname)
set @auditstring=@auditstring + 'name from '+ @oldname +' to' +@newname

if(@oldsal<>@newsal)
set @auditstring=@auditstring + ' salary from '+ @oldsal +' to ' +@newsal

if(@oldgen<>@newgen)
set @auditstring=@auditstring + ' gender from ' + @oldgen + ' to ' + @newgen

-- if(@olddeptid<>@newdeptid)
--set @auditstring=@auditstring + ' departmentid from ' + cast(@olddeptid as nvarchar(5))+' to '

insert into emp_audit values(@auditstring)

delete from #temptable where id=@Id

end
end
when i use update query
update emp set name='vishi',gender='male',salary='4000',departmentid=3 where id=3;



It gives an error



"Conversion failed when converting the nvarchar value ' Employee with id= 3 changed name from james tovishi salary from ' to data type int.
"
i don't know how to solve this..can you solve this..





Do any of the columns being logged allow NULLs?
– HABO
Jul 1 at 13:52





In emp you declare salary varchar(50), but in the trigger Declare @oldsal int,@newsal int. You ought to decide on a single datatype. Adding quotes around values makes interpreting the audit easier, e.g. from 'Foo ' to 'Foo'. As mentioned here: "Logging triggers should always be set to fire last. Otherwise, a subsequent trigger may rollback the original transaction, but the log table will have already been updated. This is a confusing state of affairs."
– HABO
Jul 1 at 15:44


emp


salary varchar(50)


Declare @oldsal int,@newsal int


from 'Foo ' to 'Foo'




3 Answers
3



The problem is in line:


if(@oldsal<>@newsal)
set @auditstring=@auditstring + ' salary from '+ @oldsal +' to ' +@newsal



Should be:


if(@oldsal<>@newsal)
set @auditstring=@auditstring+ ' salary from '+CAST(@oldsal AS NVARCHAR(100))
+' to ' +CAST(@newsal AS NVARCHAR(100))



A couple of thoughts:


@oldsal<>@newsal


NULL


NULL


set @auditstring=@auditstring +....


set @auditstring += ...


NULL


NULL


CHAR(size)


VARCHAR(size)





Thanks Lukasz for giving me some tips regarding this.Once i do update in my trigger if problem occurs i will ask again.
– Avish
Jul 1 at 10:06





All good thoughts. This can be done with a set-based operation by joining the inserted and deleted virtual tables on Id, using CASE expressions to detect changed values, and using FOR XML to build the audit string.
– Dan Guzman
Jul 1 at 10:09


inserted


deleted


Id


CASE


FOR XML



alter trigger trigger_em_update on emp for update
as begin
Declare @Id int
Declare @oldname varchar(40),@newname varchar(40)
Declare @oldsal int,@newsal int
Declare @oldgen varchar(40),@newgen varchar(40)
Declare @olddeptid int,@newdeptid int


Declare @auditstring nvarchar(max)


--select * from deleted;

select * into #temptable from inserted;

while(Exists(select id from #temptable)) --boolean condition if there are rows are not
Begin
set @auditstring =''

--if there are many rows we still select the first one

select Top 1 @Id =id,@newname=name,@newgen=gender,@newsal=salary,@newdeptid=departmentid
from #temptable;

select Top 1 @Id =id,@oldname=name,@oldgen=gender,@oldsal=salary,@olddeptid=departmentid
from deleted where @Id=id;

set @auditstring=' Employee with id= '+CAST(@Id as varchar(20))+ ' changed '
if(@oldname<>@newname)
set @auditstring+= 'name from '+ @oldname +' to' +@newname

if(@oldsal<>@newsal)
set @auditstring+= 'salary from ' +CAST(@oldsal AS NVARCHAR(100)) + ' to ' +CAST(@newsal AS NVARCHAR(100))

if(@oldgen<>@newgen)
set @auditstring+= 'gender from ' + @oldgen + ' to ' + @newgen

if(@olddeptid<>@newdeptid)
set @auditstring+= 'departmentid from ' + cast(@olddeptid as nvarchar(5))+' to'+cast(@newdeptid as nvarchar(5))

insert into emp_audit values(@auditstring)

delete from #temptable where id=@Id

end



end
when i execute this it gives an error"String or binary data would be truncated" where i did a mistake i don't know please refer the attached screenshot enter image description here



The problem is that one of the columns used with + is a number, probably salary. But your trigger is way too complicated.


+



SQL is a set-based language. So use the sets when you can:


alter trigger trigger_em_update on emp for update
as
begin
insert into emp_audit (auditstring) -- guessing the name
select ('Employee with id k= ' + CAST(@Id as varchar(20))+ ' changed ' +
(case when @oldname <> @newname
then 'name from '+ @oldname +' to ' + @newname + ' '
else ''
end) +
(case when @oldsal <> @oldsal
then 'salary from '+ convert(varchar(255), @oldsal) +' to ' + concvert(varchar(255), @newsal) + ' '
else ''
end) +
(case when @oldgen <> @newgen
then 'gender from '+ convert(varchar(255), @oldgen) +' to ' + concvert(varchar(255), @newgen) + ' '
else ''
end) +
(case when @olddeptid <> @newdeptid
then 'departmentid from '+ convert(varchar(255), @olddeptid) +' to ' + concvert(varchar(255), @newdeptid) + ' '
else ''
end)
) as auditstring
from inserted i join
deleted d
on i.id = d.id;
end;






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

n8 dn 3F7zzCYF HVt
Ns voROPY c9M78Py9eiF4WBV1 W3L91gVCU5D7e SPu Aq,zLY1cC7FJGo4R,zX5,QEQN

Popular posts from this blog

PySpark - SparkContext: Error initializing SparkContext File does not exist

django NoReverseMatch Exception

List of Kim Possible characters