Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) триггер на перехват событий создания, удаления и изменения (число прочтений - 6600 )
marina
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 37
Зарегистрирован: 14. Июня 2009
триггер на перехват событий создания, удаления и изменения
22. Июня 2009 :: 20:10
Печать  
Пишу триггер на создание, изменение и удаление элементов справочника.


     ИмяТриггера1 = ИмяТриггера+"_"+Сущность;
     
    SQLудаление1 ="IF EXISTS (SELECT name From sysobjects Where Name = N'" + ИмяТриггера1 + "'
    |AND  type = 'TR')
    |DROP TRIGGER " + ИмяТриггера1;
     
    SQLсоздание1 ="CREATE TRIGGER " + ИмяТриггера1 + " ON " +  Таблица + " FOR DELETE, INSERT, UPDATE
    | AS
     | set nocount on
    | BEGIN
     |
     | insert into [Journal].[dbo].[TemporaryTableSQL] (Number,Data,GUID,Entity,Operation,Status)
     | select newid(),getdate(),inserted."+ПолеСГуидом+",'"+Сущность+"','Add','New'
     | from inserted
    | inner join deleted
    | on inserted."+ПолеСГуидом+" = deleted."+ПолеСГуидом+"
     | where (inserted.ismark = 0) and (deleted.ismark = 1);
     |
     | insert into [Journal].[dbo].[TemporaryTableSQL] (Number,Data,GUID,Entity,Operation,Status)
     | select newid(),getdate(),inserted."+ПолеСГуидом+",'"+Сущность+"','Delete','New'
     | from inserted
    | inner join deleted
    | on inserted."+ПолеСГуидом+" = deleted."+ПолеСГуидом+"
     | where (inserted.ismark = 1) and (deleted.ismark = 0);
     |
     | insert into [Journal].[dbo].[TemporaryTableSQL] (Number,Data,GUID,Entity,Operation,Status)
     | select newid(),getdate(),inserted."+ПолеСГуидом+",'"+Сущность+"','Change','New'
     | from inserted
    | inner join deleted
    | on inserted."+ПолеСГуидом+" = deleted."+ПолеСГуидом+"
     | where (inserted.ismark = 0) and (deleted.ismark = 0);
     |
    | End " ;


ПолеСГуидом = ID. Почему-то все события задваиваются, а при создании элемента идет событие добавления и изменения. В чем может быть проблема?
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: триггер на перехват событий создания, удаления и изменения
Ответ #1 - 23. Июня 2009 :: 07:43
Печать  
marina,
вы упорно id называете ГУИДомУлыбка
если нужно отловить факт изменения объекта, имхо, можно сделать проще. Можно выделить распределенную базу. Назвать, скажем, "UPD". Все нужные объекты пометить в доп. настройках на миграцию в эту БД. После этого 1С будет вам сама складывать в _1supdts все изменения этих объектов. Далее отрабатываете как вам нужно эти изменения, чистите _1supdts для dbsign = 'UPD'
  
Наверх
 
IP записан
 
marina
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 37
Зарегистрирован: 14. Июня 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #2 - 23. Июня 2009 :: 13:39
Печать  
Называю ГУИДом потому, что изначально по ТЗ добавляли поле ГУИД типа строка(36).
База распределенная, но мне еще нужно отловить изменения, пришедшие по OLE, триггер уже написан, просто хотелось скорректировать его, чтоб работал правильно.
Может кто знает, почему события задваиваются?
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: триггер на перехват событий создания, удаления и изменения
Ответ #3 - 23. Июня 2009 :: 18:18
Печать  
marina писал(а) 23. Июня 2009 :: 13:39:
триггер уже написан, просто хотелось скорректировать его, чтоб работал правильно.

улыбнулоУлыбка
"изменения, пришедшие по OLE" вариант, который я предложил прекрасно отловитУлыбка ну да ладно. Хотя советую все-таки подумать, если можно обойтись практически штатными средствами, зачем выдумывать себе проблемы?
--
1.Триггеры тогда уж нужно сделать отдельно на FOR DELETE/INSERT/UPDATE
2.К чему эти соединения on inserted."+ПолеСГуидом+" = deleted."+ПолеСГуидом+" и отборы по ismark? При FOR DELETE берите записи из deleted, при UPDATE - из inserted и т.д.
кстати при автообмене, 1С всегда удаляет запись из таблицы(справочника), если ID существует, и добавляет новую. Т.е. будет Delete и AddNew(с тем же id) при каждом автообмене.(Да и там еще много сюрпризов вас ждут с вашим ГУИДомУлыбка)

зы: что-то не то у вас в ТЗ с этим ГУИДом, уж извините.
ззы: вообще, посоветовал бы лучше "въехать" в структуру таблиц 1С.
  
Наверх
 
IP записан
 
marina
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 37
Зарегистрирован: 14. Июня 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #4 - 24. Июня 2009 :: 19:42
Печать  
alexdd писал(а) 23. Июня 2009 :: 07:43:
marina,
вы упорно id называете ГУИДомУлыбка
если нужно отловить факт изменения объекта, имхо, можно сделать проще. Можно выделить распределенную базу. Назвать, скажем, "UPD". Все нужные объекты пометить в доп. настройках на миграцию в эту БД. После этого 1С будет вам сама складывать в _1supdts все изменения этих объектов. Далее отрабатываете как вам нужно эти изменения, чистите _1supdts для dbsign = 'UPD'


Дело в том, что размер базы очень большой, при создании новой периферийной базы прийдется скопировать все содержимое базы в базу upd. При этом размер базы существенно растет ежедневно, т.е. постоянно наполнять и растить базу будет проблематично, и думаю, на это не пойдет заказчик.

А задвоение записей решит переписывание триггера отдельно на update, delete, insert?
  
Наверх
 
IP записан
 
marina
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 37
Зарегистрирован: 14. Июня 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #5 - 24. Июня 2009 :: 19:45
Печать  
По поводу ГУИДа - не поняла какие там сюрпризы? ГУИД на текущий момент заменен на ID и IDDOC, осталось просто название в качестве параметра функции.
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: триггер на перехват событий создания, удаления и изменения
Ответ #6 - 27. Июня 2009 :: 09:13
Печать  
>при создании новой периферийной базы прийдется скопировать все содержимое базы в базу upd
Зачем копировать? Достаточно, если мне не изменяет память, сделать выгрузку один раз для новой БД и она будет инициализирована. Загружать не нужно.
Но, может действительно, это не совсем кошерный вариант, если система разрабатывается не "для себя", а для заказчика..фз)

>А задвоение записей решит переписывание триггера отдельно на update, delete, insert?
CREATE TRIGGER (Transact-SQL)
Задвоения, я думаю, связаны с "ПолемСГУИДом". Например, при создании нового элемента, как пишется значение в "ПолеСГУИДом"? Элемент записывается с пустым ГУИДом в ПриЗаписи(), потом, когда элемент существует, в "ПолеСГУИДом" прописывается ID? Если так, то вот вам и задвоение.
Относительно сюрпризов с ГУИДом, во-первых, ну не ГУИДы это ни разу(ID и IDDOC)Улыбка, во-вторых, если ПолеСГУИДом = ID||IDDOC, то зачем оно нужно в таблицах? По ID и IDDOC уникальные индексы, по ПолеСГУИДом возможны повторы(несмотря на все потуги избежать этого в коде 1С). А судя по тому, как вы используете это поле, оно должно быть уникальным.
  
Наверх
 
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: триггер на перехват событий создания, удаления и изменения
Ответ #7 - 27. Июня 2009 :: 16:56
Печать  
Автор напесал триггер и не удосужился заглянуть в профайлер?  Подмигивание
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
marina
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 37
Зарегистрирован: 14. Июня 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #8 - 08. Июля 2009 :: 17:11
Печать  
К сожалению, мне достался уже готовый триггер, я с ним разбираюсь. Сейчас все работает - пишет 1 раз. Но возникла такая проблемка. Нужно события, которые приходят под определенным пользователем не обрабатывать. Как это можно реализовать?
  
Наверх
 
IP записан
 
leov-001
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 150
Зарегистрирован: 05. Марта 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #9 - 09. Июля 2009 :: 05:05
Печать  
При начале работы системы

Код
Выбрать все
ЗапросСкл.Выполнить("INSERT INTO T_1Susers (Username,spid)
			|VALUES('"+ИмяПользователя()+"',@@spid)");
 



При завершении удаляешь
Из этой таблицы используй @@spid

  
Наверх
 
IP записан
 
marina
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 37
Зарегистрирован: 14. Июня 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #10 - 09. Июля 2009 :: 09:09
Печать  
T_1Susers - это дополнительная таблица? В смысле не 1Susers? Может можно использовать 1Susers, 1с сама пишет в нее при входе пользователя и удаляет запись при выходе?
  
Наверх
 
IP записан
 
marina
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 37
Зарегистрирован: 14. Июня 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #11 - 09. Июля 2009 :: 10:19
Печать  
SELECT @User_1c = User_1c FROM dbo.T_1Susers where PID = @@SPID - так получим пользователя, который сделал изменения. Верно?

А потом условие
IF @User_1c <> 'Test' rollback tran
если транзакция под пользователем test, то rollback
Так?
  
Наверх
 
IP записан
 
leov-001
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 150
Зарегистрирован: 05. Марта 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #12 - 09. Июля 2009 :: 11:00
Печать  
marina писал(а) 09. Июля 2009 :: 09:09:
T_1Susers - это дополнительная таблица? В смысле не 1Susers? Может можно использовать 1Susers, 1с сама пишет в нее при входе пользователя и удаляет запись при выходе?


Нет не пойдет в _1Susers два поля

Код
Выбрать все
USRSCNT
Синтаксис:
USRSCNT
Назначение:
Количество подключенных пользователей к 1С в режиме 1С предприятия 



И
Код
Выбрать все
NETCHGCN
Синтаксис:
NETCHGCN
Назначение:
Счетчик действий пользователей, которые привели к изменению в
базе данных (записи в таблицы). Счетчик учитывает количество
записей в таблицы (т.е. в случае проведения документа с
несколькими движениями учитывается каждое движение)
 


  
Наверх
 
IP записан
 
leov-001
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 150
Зарегистрирован: 05. Марта 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #13 - 09. Июля 2009 :: 11:08
Печать  
Код
Выбрать все
ЗапросСкл.Выполнить("INSERT INTO T_1Susers (Username,spid)
			|VALUES('"+ИмяПользователя()+"',@@spid)");

Username | spid | FL1 | FL2 ....
__________________________
Vasya	 | 63   | 1    | 0 ........
 



Здесь можно еще и все настройки пользователя разместить
В виде флагов 1(0)
  
Наверх
 
IP записан
 
marina
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 37
Зарегистрирован: 14. Июня 2009
Re: триггер на перехват событий создания, удаления и изменения
Ответ #14 - 09. Июля 2009 :: 13:43
Печать  
Сделала дополнительную таблицу, пишет, удалаяет, правда я через Ado делала, мне так привычней. А вот триггер не работает. Под этим пользователем пишет в таблицу TemporaryTableSQL, хотя не должен. Может что не так делаю.

    SQLсоздание1 ="CREATE TRIGGER " + ИмяТриггера1 + " ON " +  Таблица + " FOR DELETE, INSERT, UPDATE 
    | AS 
     |DECLARE @Username as varchar(50)
     |SELECT @Username = Username FROM [Journal].[dbo].[T_1Susers] where spid = @@SPID
     | set nocount on
    | BEGIN
     |
     | insert into [Journal].[dbo].[TemporaryTableSQL] (Number,Data,GUID,Entity,Operation,Status)
     | select newid(),getdate(),inserted."+ПолеСГуидом+",'"+Сущность+"','Add','New'
     | from inserted
    | inner join deleted
    | on inserted."+ПолеСГуидом+" = deleted."+ПолеСГуидом+"
     | where (inserted.ismark = 0) and (deleted.ismark = 1);
     |
     | insert into [Journal].[dbo].[TemporaryTableSQL] (Number,Data,GUID,Entity,Operation,Status)
     | select newid(),getdate(),inserted."+ПолеСГуидом+",'"+Сущность+"','Delete','New'
     | from inserted
    | inner join deleted
    | on inserted."+ПолеСГуидом+" = deleted."+ПолеСГуидом+"
     | where (inserted.ismark = 1) and (deleted.ismark = 0);
     |
     | insert into [Journal].[dbo].[TemporaryTableSQL] (Number,Data,GUID,Entity,Operation,Status)
     | select newid(),getdate(),inserted."+ПолеСГуидом+",'"+Сущность+"','Change','New'
     | from inserted
    | inner join deleted
    | on inserted."+ПолеСГуидом+" = deleted."+ПолеСГуидом+"
     | where (inserted.ismark = 0) and (deleted.ismark = 0);
     |IF @Username = 'Test' rollback tran
     |
    | End " ;


  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать