Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Сравнение значений в триггере  [new]
Hahol
Member

Откуда:
Сообщений: 21
Господа,

Стала вот задача отследить в тригере изменилось ли поле и если да то обновить дату в этой строчке.
Вижу что есть волшебная функция UPDATE(Имя_Колонки), но она меня не устравает ибо при обновлении
одним и тем же значением всегда возращается true.
Сейчас проверяю обновилось ли поле вот так:

-- создание курсора и т.д
-- id - старое значение, id2 - новое
-- .......................
if (id != id2 or (id is null and id2 is not null) or (id is not null and id2 is null))
begin
   -- обновляю дату
end
У меня таких проверок должно быть много, а плодить плохой код как то нет желания.
Может есть более изящьное решение?

Зарание благодарен!
29 авг 11, 15:06    [11195418]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iljy
Member

Откуда:
Сообщений: 8711
Hahol,

нахрена курсор? И забудьте про функцию UPDATE, она практически бесполезна. Версия сервера какая? Для 2005 и выше:
UPDATE t1
set DT = GetDate()
from inserted i join deleted d on i.id = d.id and not exists(select i.Field intersect select d.Field)
    join MyTable t1 on i.id = t1.id
29 авг 11, 15:13    [11195473]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5122
ну в тригере можно апдейтить на основе сравнения таблиц inserted и deleted
29 авг 11, 15:13    [11195475]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Hahol,

где это такой if пишете?? В SELECTе?
Так нельзя!

Кроме того, id - это первичный ключ таблицы? И он меняется?
Тогда без альтернативного ключа не обойтись. Разве что если есть гарантия, что запись всегда одна.

Так что приведите скрипт создания таблицы.
И что хотите в триггере сделать поподробнее опишите.

И версию сервера обязательно назовите!
29 авг 11, 15:23    [11195570]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
Hahol
Member

Откуда:
Сообщений: 21
Сервер MSSQL 2005

Упражняюсь на такой таблице:

CREATE TABLE [dbo].[Rows]
(
	[Id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
	[Qty] [int] NULL,
	[LastUpdate] [datetime] NULL
)

В реальной таблице полей будет больше.

Триггер:

ALTER TRIGGER [dbo].[Rows_INSERT_UPDATE] ON [dbo].[Rows]
WITH EXECUTE AS CALLER
FOR INSERT, UPDATE
AS
BEGIN
 declare
   @dId int,
   @dQty int,
   @iId int,
   @iQty int  
    
declare @changes cursor; 
set @changes = cursor local fast_forward for
select 
 d.Id dId,
 d.Qty dQty,
 i.Id iId,
 i.Qty iQty
from inserted i 
left join deleted d  on i.Id = d.Id

  open @changes;
  fetch next from @changes
  into @dId, @dQty, @iId, @iQty
  while @@FETCH_STATUS = 0
  begin  
 
    -- select @dQty as OLD, @iQty as NEW
    if (@dQty != @iQty or (@dQty is null and @iQty is not null) or (@dQty is not null and @iQty is null))
       begin
           select 'UPDATE record'
       end
   fetch next from @changes
   into @dId, @dQty, @iId, @iQty
  end 
END


Хочеться что-бы при изменении Qty обновлялась LastUpdate, если же количество обовили тем же значением что и было раньше
дата не менялась
29 авг 11, 15:34    [11195671]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
ALTER TRIGGER [dbo].[Rows_INSERT_UPDATE] ON [dbo].[Rows]
WITH EXECUTE AS CALLER
FOR UPDATE AS
SET NOCOUNT ON;
UPDATE R
SET R.[LastUpdate]=CURRENT_TIMESTAMP
FROM [dbo].[Rows] R
JOIN deleted d ON R.id=d.id
WHERE NOT EXISTS(SELECT R.[Qty] INTERSECT SELECT d.[Qty]);
29 авг 11, 15:41    [11195727]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Непонятно, что Вы собрались апдейтить при INSERTе.
Достаточно сделать CONSTRAINT DEFAULT для [LastUpdate].
Без всяких триггеров.
29 авг 11, 15:42    [11195741]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31969
iap
Непонятно, что Вы собрались апдейтить при INSERTе.
Достаточно сделать CONSTRAINT DEFAULT для [LastUpdate].
Без всяких триггеров.
Не сработает при обновлении записей...
29 авг 11, 15:53    [11195850]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
Hahol
Member

Откуда:
Сообщений: 21
>> Достаточно сделать CONSTRAINT DEFAULT для [LastUpdate].
Вы имеете ввиду что при создании таблицы:

LastUpdate Datetime default getdate()

и еще один момент, а вот при добавлении нового столбца, например Qty2, необходимо будет писать новый запрос или можно как-то все это сделать одним запросом?
29 авг 11, 15:55    [11195869]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
alexeyvg
iap
Непонятно, что Вы собрались апдейтить при INSERTе.
Достаточно сделать CONSTRAINT DEFAULT для [LastUpdate].
Без всяких триггеров.
Не сработает при обновлении записей...
Я ж написал "при INSERTе"?
29 авг 11, 15:58    [11195897]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Hahol
>> Достаточно сделать CONSTRAINT DEFAULT для [LastUpdate].
Вы имеете ввиду что при создании таблицы:

LastUpdate Datetime default getdate()

и еще один момент, а вот при добавлении нового столбца, например Qty2, необходимо будет писать новый запрос или можно как-то все это сделать одним запросом?
В смысле, что будет, если зхотите отследить изменеия хотя бы в одном столбце?
ALTER TRIGGER [dbo].[Rows_INSERT_UPDATE] ON [dbo].[Rows]
WITH EXECUTE AS CALLER
FOR UPDATE AS
SET NOCOUNT ON;
UPDATE R
SET R.[LastUpdate]=CURRENT_TIMESTAMP
FROM [dbo].[Rows] R
JOIN deleted d ON R.id=d.id
WHERE NOT EXISTS(SELECT R.[Qty],R.[Qty2] INTERSECT SELECT d.[Qty],d.[Qty2]);
29 авг 11, 15:59    [11195917]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
J.d
Member

Откуда: Москва
Сообщений: 691
жесть какая-то =)

update r
inner join 
(
select i.id from inserted i
inner join deleted d on d.id = i.id
where d.Qty != i.Qty
) N on N.id = r.id
from dbo.Rows R
set r.lastupdate = getdate()

или типа того))))
29 авг 11, 16:05    [11195967]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
J.d
Member

Откуда: Москва
Сообщений: 691
это всмысле тело триггера пихатЬ! )))
29 авг 11, 16:06    [11195976]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
Hahol
Member

Откуда:
Сообщений: 21
Господа, всем спасибо за помощь!

iap, Ваше решение очень изящное :)
29 авг 11, 16:08    [11195999]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
innerjoin2
Guest
J.d
жесть какая-то =)

update r
inner join 
(
select i.id from inserted i
inner join deleted d on d.id = i.id
where d.Qty != i.Qty
) N on N.id = r.id
from dbo.Rows R
set r.lastupdate = getdate()

или типа того))))


синтаксис с какой планеты?
29 авг 11, 16:10    [11196010]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
J.d,

Вы, наверно, из Oracle сюда зашли?
Хотя, до конца не уверен
29 авг 11, 16:11    [11196014]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
J.d
Member

Откуда: Москва
Сообщений: 691
iap
J.d,

Вы, наверно, из Oracle сюда зашли?
Хотя, до конца не уверен


не ну понятно что имелось ввиду

update r
set r.lastupdate = getdate()
inner join 
(
select i.id from inserted i
inner join deleted d on d.id = i.id
where d.Qty != i.Qty
) N on N.id = r.id
from dbo.Rows R

=) опечатка

не, я не оракловод, увольте)
29 авг 11, 16:14    [11196044]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
J.d
Member

Откуда: Москва
Сообщений: 691
=)) т.е
update r
set r.lastupdate = getdate()
from dbo.Rows R
inner join 
(
select i.id from inserted i
inner join deleted d on d.id = i.id
where d.Qty != i.Qty
) N on N.id = r.id
29 авг 11, 16:15    [11196054]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
J.d,

а зачем там inserted, если она совпадает с таблицей?
В пределах затронутых записей, разумеется.
Но это отслеживается JOINом с deleted
29 авг 11, 16:39    [11196237]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
J.d,

плюс ко всему, если NULL меняется на не-NULL или наоборот, Ваш скрипт это не отследит.
29 авг 11, 16:40    [11196244]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
J.d
Member

Откуда: Москва
Сообщений: 691
iap
J.d,

плюс ко всему, если NULL меняется на не-NULL или наоборот, Ваш скрипт это не отследит.


тут согласен - не учёл.

а про join с inserted - мне кажется это просто более общий случай )
ваш вариант конечно же правильнее.
29 авг 11, 16:53    [11196317]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
J.d
Member

Откуда: Москва
Сообщений: 691
просто мне не оч понравился вложенный запрос where not exists =)
29 авг 11, 16:56    [11196336]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
J.d
просто мне не оч понравился вложенный запрос where not exists =)
Который сравнивает пары констант?
Да ещё по возможности использует индексы?
29 авг 11, 17:25    [11196588]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
step_ks
Member

Откуда:
Сообщений: 936
iap
J.d,

а зачем там inserted, если она совпадает с таблицей?

Теоретически, при большой таблице Rows так может быть меньше шансов просесть на плохом плане джойна по id. Но не факт, конечно.
29 авг 11, 20:56    [11197702]     Ответить | Цитировать Сообщить модератору
 Re: Сравнение значений в триггере  [new]
step_ks
Member

Откуда:
Сообщений: 936
step_ks
iap
J.d,

а зачем там inserted, если она совпадает с таблицей?

Теоретически, при большой таблице Rows так может быть меньше шансов просесть на плохом плане джойна по id. Но не факт, конечно.

А, прошу прощения. Комментарий отменяется, был невнимателен.
29 авг 11, 20:58    [11197713]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить