SQL триггеров-реализация вопроса - PullRequest
0 голосов
/ 01 июля 2018

Привет, ребята, я делаю 2 таблицы для реализации триггеров -

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;

выдает ошибку

"Сбой преобразования при преобразовании значения nvarchar" Сотрудник с id = 3 изменил имя с оклада james tovishi с "на тип данных int. " я не знаю, как решить это .. вы можете решить это ..

Ответы [ 3 ]

0 голосов
/ 01 июля 2018

изменить триггер trigger_em_update на emp для обновления как начать Объявите @Id int Объявите @oldname varchar (40), @ newname varchar (40) Объявите @oldsal int, @ newsal int Объявите @oldgen varchar (40), @ newgen varchar (40) Объявите @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

конец когда я выполняю это, он выдает ошибку «Строка или двоичные данные будут обрезаны», где я сделал ошибку, которую я не знаю, пожалуйста, обратитесь к приложенному снимку экрана введите описание изображения здесь

0 голосов
/ 01 июля 2018

Проблема в том, что один из столбцов, используемых с + - это число, возможно, оклад. Но ваш триггер слишком сложный.

SQL - это язык на основе множеств. Поэтому используйте наборы, когда можете:

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;
0 голосов
/ 01 июля 2018

Проблема в строке:

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

Должно быть:

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

Пара мыслей:

  1. Рекомендуется заканчивать каждое утверждение точкой с запятой
  2. @oldsal<>@newsal не обнаружит изменения с NULL на значение или значение на NULL
  3. Строковая обработка не является лучшей практикой с точки зрения производительности (особенно внутри тела триггера)
  4. set @auditstring=@auditstring +.... можно заменить на set @auditstring += ...
  5. Если какое-либо значение, которое вы используете для объединения строки аудита, равно NULL, переменная будет установлена ​​на NULL.
  6. Я не рекомендую хранить имя / переменную как CHAR(size), лучше использовать VARCHAR(size)
  7. Отслеживание того, что изменилось как одна строка, потребует анализа в будущем (если только вы не хотите отображать это).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...