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

Откуда: Норильск
Сообщений: 940
Всем доброго дня. Замучилась гуглить, поэтому спрошу здесь.

Есть таблица, в ней больше 50 полей. И есть такая же таблица After_upd с таким же кол-вом полей для внесения изменений.

Т.е. пользователь, например, изменил поле1 и поле33, и в таблицу After_upd в поле1 соответственно должно заноситься новое значение поле1, а в поле33 - новое значение поле33, а остальные, неизмененные поля, должны быть пустыми.

Делаю триггер


CREATE TRIGGER [dbo].[trg_upd]
   ON  [dbo].[Main_table]
   AFTER UPDATE 
AS 
begin		  	 
	   INSERT INTO After_upd
	   SELECT 
	   CASE WHEN i.поле1<>d.поле1 THEN i.поле1 ELSE null END AS поле1,   
               ..... и далее здесь перечисления всех полей	    

              from inserted i join deleted d on i.id = d.id
END


Вопрос: как сделать тоже самое, но с циклом по всем полям? Только без курсора. Всем заранее спасибо.
19 окт 16, 13:07    [19799427]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
buven
Member

Откуда:
Сообщений: 792
Настенька
Всем доброго дня. Замучилась гуглить, поэтому спрошу здесь.

Есть таблица, в ней больше 50 полей. И есть такая же таблица After_upd с таким же кол-вом полей для внесения изменений.

Т.е. пользователь, например, изменил поле1 и поле33, и в таблицу After_upd в поле1 соответственно должно заноситься новое значение поле1, а в поле33 - новое значение поле33, а остальные, неизмененные поля, должны быть пустыми.

Делаю триггер


CREATE TRIGGER [dbo].[trg_upd]
   ON  [dbo].[Main_table]
   AFTER UPDATE 
AS 
begin		  	 
	   INSERT INTO After_upd
	   SELECT 
	   CASE WHEN i.поле1<>d.поле1 THEN i.поле1 ELSE null END AS поле1,   
               ..... и далее здесь перечисления всех полей	    

              from inserted i join deleted d on i.id = d.id
END


Вопрос: как сделать тоже самое, но с циклом по всем полям? Только без курсора. Всем заранее спасибо.


Добавиться поле - будете дорабатывать триггер? ИМХО не комильфо
Проще after_upd сделать before_update, как полную копиею Main, с добавлением 3-х полей : action,ModDate,ModUser и писать последнее состояние до адейта туда.
Все остальное делать уже на клиенте.
Удаление же наверняка потом захотите логировать.
19 окт 16, 13:18    [19799518]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Настенька,

в смысле каждое изменённое поле в отдельной строке?
19 окт 16, 13:18    [19799521]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8828
Настенька,

автор
Вопрос: как сделать тоже самое, но с циклом по всем полям?


А цикл зачем? Самоцель, что ли?
19 окт 16, 13:21    [19799549]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
Настенька
Member

Откуда: Норильск
Сообщений: 940
автор
Добавиться поле - будете дорабатывать триггер? ИМХО не комильфо


Доработаю - ничего страшного.

автор
в смысле каждое изменённое поле в отдельной строке?


Нет же, просто в одной вставляемой строке будут поля, которые изменены, в них будет значение, а остальные будут пустые.

Про цикл то кто-нибудь подскажет? Вроде легкий же вопрос.
19 окт 16, 13:22    [19799562]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Настенька
автор
Добавиться поле - будете дорабатывать триггер? ИМХО не комильфо


Доработаю - ничего страшного.

автор
в смысле каждое изменённое поле в отдельной строке?


Нет же, просто в одной вставляемой строке будут поля, которые изменены, в них будет значение, а остальные будут пустые.

Про цикл то кто-нибудь подскажет? Вроде легкий же вопрос.

я так понимаю ответ на вопрос
автор
..... и далее здесь перечисления всех полей
19 окт 16, 13:24    [19799576]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
Настенька
Member

Откуда: Норильск
Сообщений: 940
Ну неужели никак нельзя обойтись без этого перечисления (столько лишних строк кода можно заменить одной) ??? Не верю, есть способы однозначно.
19 окт 16, 13:25    [19799595]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Настенька
Ну неужели никак нельзя обойтись без этого перечисления (столько лишних строк кода можно заменить одной) ??? Не верю, есть способы однозначно.

напишите одной строкой, никто не запрещает, только сюда не выкладывайте
19 окт 16, 13:30    [19799627]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
buven
Member

Откуда:
Сообщений: 792
Настенька
Доработаю - ничего страшного.

Вы - бесспорно. Однако тут стоит подумать о наследниках. По моему опыту триггеры частенько доставляют массу неудобств. Особенно не свои. Особенно когда по названию таблиц (main_table after_upd) не просматривается их связь друг с другом...

По хорошему бы вам на клиенте логгирование докрутить и обойтись вообще без триггеров. Там и проще определять, какое из полей изменило значение.
19 окт 16, 13:31    [19799639]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
buven
Настенька
Доработаю - ничего страшного.

По хорошему бы вам на клиенте логгирование докрутить и обойтись вообще без триггеров. Там и проще определять, какое из полей изменило значение.

а вы упорный... пусть клиент и сам транзакции отслеживает, и лог свой держит ну и тд

автор
. Однако тут стоит подумать о наследниках.

занятно, а таблицы истории сами изменятся под ваши запросы? или пусть клиент и таблицы расширяет
19 окт 16, 13:33    [19799657]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
Настенька
Member

Откуда: Норильск
Сообщений: 940
Товарищи, не надо про логирование на клиенте, надо здесь, в триггере. Этот вопрос закрыт.
Отвечайте, пожалуйста, по теме вопроса.

Кроме курсора - это сделать никак нельзя?

автор
напишите одной строкой, никто не запрещает, только сюда не выкладывайте

Давайте без сарказма и троллинга.
19 окт 16, 13:37    [19799686]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Настенька
Товарищи, не надо про логирование на клиенте, надо здесь, в триггере. Этот вопрос закрыт.
Отвечайте, пожалуйста, по теме вопроса.

Кроме курсора - это сделать никак нельзя?

автор
напишите одной строкой, никто не запрещает, только сюда не выкладывайте

Давайте без сарказма и троллинга.

поймите простую вещь: триггер должен отрабатывать максимально быстро и чем меньше затраты для сервера тем лучше, вы же хотите всунуть НИКОМУ/ЛИШНЮЮ/БЕСПОЛЕЗНУЮ логику

и да гуглите в сторону динамического запроса на sys.Columns sys.Tables забивать себе гвозди в ноги не запрещено
19 окт 16, 13:42    [19799729]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
Настенька
Member

Откуда: Норильск
Сообщений: 940
Я гуглила про динамический запрос, подскажите, как правильно переписать мой запрос под динамический?
У меня не получилось. Он писал - невозможно найти таблицу Inserted.
19 окт 16, 13:44    [19799740]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
ещё и уши отморозить....
Настенька
Я гуглила про динамический запрос, подскажите, как правильно переписать мой запрос под динамический?
У меня не получилось. Он писал - невозможно найти таблицу Inserted.

SELECT * INTO #inserted From inserted
19 окт 16, 13:46    [19799751]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8828
Настенька,

а что не устраивает в
CASE WHEN i.поле1<>d.поле1 THEN i.поле1 ELSE null END AS поле1

зачем какой-то цикл делать и для чего цикл?
19 окт 16, 14:05    [19799852]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Владислав Колосов,

автор
зачем какой-то цикл делать и для чего цикл?

некрасиво... судя по всему

автор
Ну неужели никак нельзя обойтись без этого перечисления (столько лишних строк кода можно заменить одной) ?
19 окт 16, 14:08    [19799867]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
Настенька
Ну неужели никак нельзя обойтись без этого перечисления
Т.е. основная цель - избавить себя от ручного написания кода?

1. Пишите процедуру, которая по метаданным таблицы будет создавать триггер со всей необходимой логикой.
2. Пишите на таблицу DDL-триггер, который будет эту процедуру вызывать.

ЗЫ: За потраченное на форуме время можно было уже давно несколько раз написать этот триггер с перечислением столбцов...
19 окт 16, 14:44    [19800054]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Владислав Колосов
Настенька,

а что не устраивает в
CASE WHEN i.поле1<>d.поле1 THEN i.поле1 ELSE null END AS поле1


зачем какой-то цикл делать и для чего цикл?
Интересно, а как это будет работать, если NULL поменяется на не-NULL?
Честно говоря, поражаюсь: здесь есть неплохой поиск по форуму, а тема обсуждалась тысячи раз.

1. Сохранять надо не новые, а старые значения, ибо новые и так содержатся в основной таблице.
2. Правильнее всего не полагаться на идентичный порядок полей и их количество в двух похожих, но разных таблицах,
а явно перечислять все вставляемые поля.
3. Какой ещё цикл?!

Предлагаю:
IF OBJECT_ID(N'[dbo].[trg_upd]','TR') IS NULL
EXEC(N'CREATE TRIGGER [dbo].[trg_upd] ON [dbo].[Main_table] FOR UPDATE AS RETURN');
GO
ALTER TRIGGER [dbo].[trg_upd] ON [dbo].[Main_table] FOR UPDATE AS 
INSERT [dbo].[After_upd](id,F1,F2, ...,Fn,[DateOfChange],[UserName])
SELECT d.id,d.F1,d.F2, ...,d.Fn,CURRENT_TIMESTAMP,ORIGINAL_LOGIN()
FROM deleted d JOIN inserted i ON d.id=i.id
WHERE NOT EXISTS
(
 SELECT d.F1,d.F2, ...,d.Fn
 INTERSECT
 SELECT i.F1,i.F2, ...,i.Fn
);
GO
19 окт 16, 14:55    [19800124]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
Владислав Колосов
Member

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

автор
Интересно, а как это будет работать, если NULL поменяется на не-NULL?


Это очевидно, я говорю о принципе сравнения. Какие такие циклы?

Нуллами забивать совпадающие - понятно, из-за экономии места в таблице истории.
19 окт 16, 15:01    [19800181]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
Владислав Колосов
Это очевидно
Это вам очевидно.
А вот у Настеньки может мозг взорваться.
По поводу экономии места предлагаю не заморачиваться. Как-то несерьёзно это...
19 окт 16, 15:04    [19800211]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
buven
Member

Откуда:
Сообщений: 792
iap
Владислав Колосов
Это очевидно
Это вам очевидно.
А вот у Настеньки может мозг взорваться.
По поводу экономии места предлагаю не заморачиваться. Как-то несерьёзно это...


Настеньке нужно знать какое именно поле было изменено. Вот она и пытается все остальные сделать null во время события в сторонней таблице.
19 окт 16, 16:15    [19800663]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
buven
iap
пропущено...
Это вам очевидно.
А вот у Настеньки может мозг взорваться.
По поводу экономии места предлагаю не заморачиваться. Как-то несерьёзно это...


Настеньке нужно знать какое именно поле было изменено. Вот она и пытается все остальные сделать null во время события в сторонней таблице.
Могут быть изменены сразу 900 полей! Не боитесь за Настеньку?
Если информация по отдельным полям действительно понадобится,
её легко будет получить из лога с изменёнными строками целиком.
Зато такой лог получается элементарно (см. выше).
19 окт 16, 16:18    [19800688]     Ответить | Цитировать Сообщить модератору
 Re: Trigger After Insert и цикл по полям  [new]
buven
Member

Откуда:
Сообщений: 792
iap
buven
пропущено...


Настеньке нужно знать какое именно поле было изменено. Вот она и пытается все остальные сделать null во время события в сторонней таблице.
Могут быть изменены сразу 900 полей! Не боитесь за Настеньку?
Если информация по отдельным полям действительно понадобится,
её легко будет получить из лога с изменёнными строками целиком.
Зато такой лог получается элементарно (см. выше).


Посмотрите мой пост в самом начале :) Я предложил ровно то же самое.
Видимо Настенька хочет быстро находить глазками в SSMS, что когда менялось, а не кормить результаты какому то еще клиенту.
19 окт 16, 16:23    [19800719]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить