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

Откуда: СПб
Сообщений: 270
Всем добрый день!

Есть триггер, в котором протоколируются изменения.

Так вот вопрос что будет менее затратно для системы через курсор выбрать значения в переменные
DECLARE NEW2_cursor CURSOR For
 SELECT ID, FIELD1, FIELD2, ..., FIELDn
 FROM INSERTED
 OPEN NEW2_cursor;
 FETCH NEXT FROM NEW2_cursor INTO 
  @ID, @VarNew1, @VarNew2, ..., @VarNewN

DECLARE OLD2_cursor CURSOR For
 SELECT ID, FIELD1, FIELD2, ..., FIELDn
 FROM DELETED
 OPEN OLD2_cursor;
 FETCH NEXT FROM OLD2_cursor INTO 
  @ID, @VarOld1, @VarOld2, ..., @VarOldN
 


и далее соответственно так для каждого поля

 IF UPDATE(FIELD1)
   INSERT INTO [dbo].[00_SYS_AUDIT] ([TABLE],[FIELD],[OLD],[NEW],[STATUS],[DATATIME],[USER])
     VALUES ('Table1','FIELD1',@VarOld1,@VarNew1,'diff',@DTIME,USER_NAME());


или сделать так для каждого поля

  IF UPDATE (FIELD1)
    INSERT INTO [dbo].[00_SYS_AUDIT] ([TABLE],[FIELD],[OLD],[NEW],[STATUS],[DATATIME],[USER])
    SELECT @tid, , 'FIELD1', d.FIELD1, i.FIELD1, 'diff', @DTIME, USER_NAME()
    FROM
      DELETED AS d INNER JOIN INSERTED AS i
        ON d.id = i.id;


Подскажите, что будет быстрее работать и особо не загружать систему????
8 апр 13, 14:21    [14151483]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Веткин Сергей,

Вариант — "сделать структуру таблицы лога совпадающей со структурой протоколируемой таблицы, плюс служебные поля" — не рассматривается?
8 апр 13, 14:33    [14151598]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
vso
Member

Откуда: СПб
Сообщений: 270
Гость333,

1. Я не имею представления каков порядок действий в этом случае.
2. В этом случае получается, что на каждую таблицу надо делать таблицу "двойник"?
8 апр 13, 14:51    [14151734]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31444
Веткин Сергей
1. Я не имею представления каков порядок действий в этом случае.
2. В этом случае получается, что на каждую таблицу надо делать таблицу "двойник"?
1. Что имеется в виду? Нужно сделать триггеры на каждую таблицу, в них писать например удалённые записи. Посмотрите в ФАК, там есть варианты.

2. Да.
8 апр 13, 15:26    [14152011]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
invm
Member

Откуда: Москва
Сообщений: 9406
Веткин Сергей,

Вот вам пример:
use tempdb;
go

create table dbo.AuditTable
(
 at_id int not null identity constraint PK_AuditTable primary key,
 at_TableName sysname not null,
 at_KeyFieldName sysname not null,
 at_KeyFieldValue varchar(max) not null,
 at_FieldName sysname not null,
 at_OldValue varchar(max) null,
 at_NewValue varchar(max) null,
 at_CreateDate datetime not null constraint DF_AuditTable__at_CreateDate default (getdate()),
 at_Creator sysname not null constraint DF_AuditTable__at_Creator default (original_login())
);
go

create table dbo.TestTable
(
 id int not null primary key,
 d datetime null,
 s varchar(10) null,
 v int
);
go

create trigger dbo.tr_TestTable_Audit
on dbo.TestTable
for update
as
begin
 if not exists(select * from inserted)
  return;
 
 set nocount on;
 
 insert into dbo.AuditTable
  (at_TableName, at_KeyFieldName, at_KeyFieldValue, at_FieldName, at_OldValue, at_NewValue)
  select
   'dbo.TestTable', 'id', i.id, t.at_FieldName, t.at_OldValue, t.at_NewValue
  from
   inserted i join
   deleted d on d.id = i.id cross apply
   (
    select 'd', cast(d.d as varchar(max)), cast(i.d as varchar(max)) where update(d) union all
    select 's', cast(d.s as varchar(max)), cast(i.s as varchar(max)) where update(s) union all
    select 'v', cast(d.v as varchar(max)), cast(i.v as varchar(max)) where update(v)
   ) t(at_FieldName, at_OldValue, at_NewValue);
end;
go

insert into dbo.TestTable
values
 (1, getdate(), 'a', 0),
 (2, getdate() + 1, 'b', 1),
 (3, getdate() + 2, 'c', 2);
 
update dbo.TestTable
 set
  s = 'aa'
where
 id = 1;
 
update dbo.TestTable
 set
  d = '1900',
  s = 'bbb',
  v = 8
where
 id = 2;
 
select * from dbo.AuditTable order by at_id;
go

drop table dbo.AuditTable, dbo.TestTable;
go

Не учтена возможность изменения ключевого столбца и возможная множественность ключевых столбцов.
Так же не учтен холостой update.

ЗЫ: А лучше сделать как пишет Гость333.
8 апр 13, 15:50    [14152185]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
CDC не предлагать?
8 апр 13, 16:05    [14152305]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
vso
Member

Откуда: СПб
Сообщений: 270
alexeyvg
1. Что имеется в виду? Нужно сделать триггеры на каждую таблицу, в них писать например удалённые записи. Посмотрите в ФАК, там есть варианты.


к сожалению там ничего такого не нашел.

Jovanny
CDC не предлагать?


Что это такое?

Моя цель сделать протоколирование как можно менее обременительное для сервера. Поэтому и возник первоначальный вопрос.
8 апр 13, 21:56    [14153989]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Веткин Сергей,
плохо искали:

Журналирование изменений структуры БД и данных

Статья немного устарела, но очень содержательна.
9 апр 13, 09:32    [14154761]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
Jovanny
Member

Откуда:
Сообщений: 1195
CDC
9 апр 13, 09:50    [14154819]     Ответить | Цитировать Сообщить модератору
 Re: Производительность курсора против много раз INNER JOIN?  [new]
vso
Member

Откуда: СПб
Сообщений: 270
iap, Спасибо!

просто я искал в ФАКе...
9 апр 13, 17:05    [14158018]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить