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

Откуда: Екатеринбург
Сообщений: 20
В триггере можно использовать функцию UPDATE, чтобы определить какое именно поле изменилось, но для истории проще сохранить целиком COLUMNS_UPDATED. Да только потом возникает вопрос, как с этим набором битов работать. Ну т.е. как работать-то понятно, в справке всё есть, но может есть у кого-то примеры готовых функций, которые бы по имени поля возвращали менялось оно или нет, и наоборот по набору битов возвращали имена полей, которые изменились? Думаю это стоит того, чтобы быть помещённым в FAQ, также как преобразование даты в строку, например. :)

Ну и ещё один щекотливый вопрос, в каких случаях может изменится порядок полей в таблице? Например, столбец удалили, как вариант. Какие ещё "возможности" для этого? :)

З.Ы. Честно признаюсь, поиском по форуму не увлекался, но в тех темах, которые просматривал, изящного решения не нашёл :)
В частности:
https://www.sql.ru/forum/actualthread.aspx?tid=441997
https://www.sql.ru/forum/actualthread.aspx?tid=548011
Число полей естественно больше 8. :)
24 авг 11, 17:34    [11173076]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
Glory
Member

Откуда:
Сообщений: 104764
VladBoyr
и наоборот по набору битов возвращали имена полей, которые изменились?

Пример B. Using COLUMNS_UPDATED to test more than eight columns из хелпа разве не делает это ?
24 авг 11, 17:41    [11173140]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30763
VladBoyr
В триггере можно использовать функцию UPDATE, чтобы определить какое именно поле изменилось, но для истории проще сохранить целиком COLUMNS_UPDATED.
UPDATE и COLUMNS_UPDATED не возвращает поля, которые изменились.

Сравнивайте значения из inserted и deleted
24 авг 11, 17:44    [11173184]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10240
Блог
http://support.microsoft.com/kb/232195
24 авг 11, 17:47    [11173204]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
SamMan
Member

Откуда: Moscow
Сообщений: 759
VladBoyr
Например, столбец удалили, как вариант.


Такой вариант прокатывает только как результат команды ALTER TABLE. У UPDATE такое не получится ни в жисть - даже класс команды не тот.
24 авг 11, 17:56    [11173269]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
SamMan
Member

Откуда: Moscow
Сообщений: 759
Хотя я может вопрос
VladBoyr
Ну и ещё один щекотливый вопрос, в каких случаях может изменится порядок полей в таблице?

не так интерпретировал? Тогда - сорри.
24 авг 11, 17:58    [11173280]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
VladBoyr
Member

Откуда: Екатеринбург
Сообщений: 20
alexeyvg
VladBoyr
В триггере можно использовать функцию UPDATE, чтобы определить какое именно поле изменилось, но для истории проще сохранить целиком COLUMNS_UPDATED.
UPDATE и COLUMNS_UPDATED не возвращает поля, которые изменились.

Сравнивайте значения из inserted и deleted
А что же они возвращают? Я вас не понимаю. %)

Мне и не надо в триггере ничего делать. В триггере у меня идёт журналирование, в таблицу History попадают те поля, которые были изменены по update. Мне нужно по прошествии какого-то времени восстановить по истории какие поля изменились. Соответственно, я не могу использовать служебные объекты inserted и deleted, у меня есть лишь поле varbinary(10). Вот для работы с этим полем, для собственного удобства, и написал пару простеньких функций. Задолбался с битовыми масками %)

Базовая функция
alter function dbo.IsItTrue(@Columns_Updated varbinary(10), @ColumnId int)
returns bit
begin
	DECLARE @numchar int, @numbit int
	---
	SET @ColumnId = @ColumnId - 1
	SET @numchar =(@ColumnId / 8) + 1
	SET @numbit = power(2,@ColumnId % 8)
	
	IF SUBSTRING(@Columns_Updated,@numchar,1) & @numbit = @numbit return 1 
	
	return 0
end

Функция №1
alter function dbo.IsThisUpdated(@Columns_Updated varbinary(10), @Table varchar(255), @Column varchar(255))
returns bit
begin
	DECLARE @ColumnId int
	---
	SET @ColumnId = COLUMNPROPERTY(OBJECT_ID(@Table), @Column, 'ColumnID')
	
	IF dbo.IsItTrue(@Columns_Updated,@ColumnId) = 1 return 1 
	
	return 0
end

Функция №2
alter function dbo.WhoIsUpdated(@Columns_Updated varbinary(10), @Table varchar(255))
returns @WhoIsUpdated table (ColumnId int, ColumnName varchar(255))
begin
	Insert Into @WhoIsUpdated (ColumnId, ColumnName) 
	Select column_id, name From sys.columns 
	 Where object_id = OBJECT_ID(@Table)
	   and dbo.IsItTrue(@Columns_Updated,column_id) = 1

	return
end
25 авг 11, 15:16    [11178829]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
VladBoyr
Member

Откуда: Екатеринбург
Сообщений: 20
SamMan, я наверное просто не очень ясно выразился. %)
Ну в общем, если порядок полей меняется, то мы имеем кучу недостоверной информации в поле ColumnsUpdated.
Таким образом интересует как обезопасить себя от этого? Например:
1. Не удалять столбцы в таблицах.
2. ...
и т.д.?
25 авг 11, 15:21    [11178897]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
SamMan
Member

Откуда: Moscow
Сообщений: 759
VladBoyr
Ну в общем, если порядок полей меняется, то мы имеем кучу недостоверной информации в поле ColumnsUpdated.


Это что за поле такое - ColumnsUpdated? В какой таблице? И как эта гадкая "недостоверная информация" в него попадает?
25 авг 11, 15:36    [11179054]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
iap
Member

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

чего-то не понимаю. Вам же уже, кажется, посоветовали забыть о существовании функции COLUMNS_UPDATED()
ввиду её полной практической бесполезности. Ибо она возвращает установленные биты для полей, перечисленных в команде
UPDATE [Table] SET Field1=..., Field2=..., Field3=...
Причём результат не зависит от того, поменялось значение поля или нет.
25 авг 11, 15:50    [11179224]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
iap
посоветовали забыть о существовании функции COLUMNS_UPDATED()

но если поле не упоминалось в update, можно с уверенностью утверждать, что оно не менялось )
25 авг 11, 16:01    [11179358]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
iap
Member

Откуда: Москва
Сообщений: 46953
Зайцев Фёдор
iap
посоветовали забыть о существовании функции COLUMNS_UPDATED()

но если поле не упоминалось в update, можно с уверенностью утверждать, что оно не менялось )
Разве что.
Очень ценно!
25 авг 11, 16:18    [11179582]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30763
VladBoyr
alexeyvg
пропущено...
UPDATE и COLUMNS_UPDATED не возвращает поля, которые изменились.

Сравнивайте значения из inserted и deleted
А что же они возвращают? Я вас не понимаю. %)
Они возвращают те поля, которые были упомянуты в инструкциях insert/update
VladBoyr
Соответственно, я не могу использовать служебные объекты inserted и deleted, у меня есть лишь поле varbinary(10).
Почему не можете? Принципы?
25 авг 11, 16:46    [11179867]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
alexeyvg
VladBoyr
пропущено...
А что же они возвращают? Я вас не понимаю. %)
Они возвращают те поля, которые были упомянуты в инструкциях insert/update
VladBoyr
Соответственно, я не могу использовать служебные объекты inserted и deleted, у меня есть лишь поле varbinary(10).
Почему не можете? Принципы?

естественный ключ. нет возможности сопоставить записи из inserted и deleted
25 авг 11, 16:57    [11179985]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 30763
Зайцев Фёдор
Почему не можете? Принципы?

естественный ключ. нет возможности сопоставить записи из inserted и deleted
В смысле, ключ меняется?

Тогда да, ничего не поделаешь.

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

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

Сообщение было отредактировано: 25 авг 11, 17:12
25 авг 11, 17:05    [11180056]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
исторически
Guest
VladBoyr,

автор
В триггере у меня идёт журналирование, в таблицу History попадают те поля, которые были изменены по update. Мне нужно по прошествии какого-то времени восстановить по истории какие поля изменились.


вы имена измененных полей историруете или данные в них?
если данные - пихайте в историю неглядя/как-то смотрите на уже имеющуюся историю.
потом уже в выборке из истории схлопывайте/подчищайте или вроде того.

и если у вас нет возможности сопоставить inserted с deleted - как вы потом по истории понимаете, кто это вообще изменился?
25 авг 11, 17:08    [11180088]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
исторически
Guest
alexeyvg
Зайцев Фёдор
Почему не можете? Принципы?

естественный ключ. нет возможности сопоставить записи из inserted и deleted
В смысле, ключ меняется?

Тогда да, ничего не поделаешь.

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

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


вариант - через вьюху с insteadof триггером и дополнительным фейковым полем (старый ключ/какой-то хэш), которое не менять в апдейте. оно придет и в inserted и в deleted со старым значением.

Сообщение было отредактировано: 25 авг 11, 17:13
25 авг 11, 17:12    [11180120]     Ответить | Цитировать Сообщить модератору
 Re: COLUMNS_UPDATED  [new]
исторически
Guest
вариант - через вьюху с insteadof триггером и дополнительным фейковым полем (старый ключ/какой-то хэш), которое не менять в апдейте. оно придет и в inserted и в deleted со старым значением.
25 авг 11, 17:14    [11180142]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: COLUMNS_UPDATED  [new]
SIMPLicity_
Member

Откуда: (((@)))
Сообщений: 8644
Офигенно!

Спасибо! Реально помогло, а то чуть было не "забил" на updated_column() ....

VladBoyr
alexeyvg
пропущено...
UPDATE и COLUMNS_UPDATED не возвращает поля, которые изменились.

Сравнивайте значения из inserted и deleted
А что же они возвращают? Я вас не понимаю. %)

Мне и не надо в триггере ничего делать. В триггере у меня идёт журналирование, в таблицу History попадают те поля, которые были изменены по update. Мне нужно по прошествии какого-то времени восстановить по истории какие поля изменились. Соответственно, я не могу использовать служебные объекты inserted и deleted, у меня есть лишь поле varbinary(10). Вот для работы с этим полем, для собственного удобства, и написал пару простеньких функций. Задолбался с битовыми масками %)

Базовая функция
alter function dbo.IsItTrue(@Columns_Updated varbinary(10), @ColumnId int)
returns bit
begin
	DECLARE @numchar int, @numbit int
	---
	SET @ColumnId = @ColumnId - 1
	SET @numchar =(@ColumnId / 8) + 1
	SET @numbit = power(2,@ColumnId % 8)
	
	IF SUBSTRING(@Columns_Updated,@numchar,1) & @numbit = @numbit return 1 
	
	return 0
end


Функция №1
alter function dbo.IsThisUpdated(@Columns_Updated varbinary(10), @Table varchar(255), @Column varchar(255))
returns bit
begin
	DECLARE @ColumnId int
	---
	SET @ColumnId = COLUMNPROPERTY(OBJECT_ID(@Table), @Column, 'ColumnID')
	
	IF dbo.IsItTrue(@Columns_Updated,@ColumnId) = 1 return 1 
	
	return 0
end


Функция №2
alter function dbo.WhoIsUpdated(@Columns_Updated varbinary(10), @Table varchar(255))
returns @WhoIsUpdated table (ColumnId int, ColumnName varchar(255))
begin
	Insert Into @WhoIsUpdated (ColumnId, ColumnName) 
	Select column_id, name From sys.columns 
	 Where object_id = OBJECT_ID(@Table)
	   and dbo.IsItTrue(@Columns_Updated,column_id) = 1

	return
end
23 окт 18, 20:54    [21712786]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить