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

Откуда: Челябинск
Сообщений: 173
ДОбрый день!
Есть триггер:
CREATE TRIGGER [dbo].[CHANGE_SORTAMENTEX] ON [dbo].[SORTAMENTEX]
AFTER INSERT, DELETE, UPDATE
as 
BEGIN
 
  SET NOCOUNT ON;
	declare @id int
 
	IF EXISTS(SELECT * FROM DELETED) AND EXISTS(SELECT * FROM INSERTED)
	begin
	DECLARE fetch_cursor CURSOR FOR  select BOLD_ID from INSERTED
	OPEN fetch_cursor

	  FETCH NEXT FROM fetch_cursor 
	  INTO @id
 
		WHILE @@FETCH_STATUS = 0 
		BEGIN
			update MISORA..DBMISIMP.SORTAMENTEX 
			set [BOLD_TYPE] = INSERTED.BOLD_TYPE,
			[OBJECTID] = INSERTED.OBJECTID,
			[NAME] = INSERTED.NAME,
			[code] = INSERTED.CODE,
			[SORTAMENTMATERIAL] = INSERTED.SORTAMENTMATERIAL,
			[TYPOSIZEVALUE] = INSERTED.TYPOSIZEVALUE,
			[OPTIONS] = INSERTED.OPTIONS
			from INSERTED where SORTAMENTEX.BOLD_ID =@id
			
			FETCH NEXT FROM fetch_cursor 
			INTO @id
		END

	CLOSE fetch_cursor
	  
	DEALLOCATE fetch_cursor 
	end;

	IF EXISTS(SELECT * FROM DELETED) AND NOT EXISTS(SELECT * FROM INSERTED)
	begin
	DECLARE fetch_cursor CURSOR FOR  select BOLD_ID from DELETED
	OPEN fetch_cursor

	  FETCH NEXT FROM fetch_cursor 
	  INTO @id
 
		WHILE @@FETCH_STATUS = 0 
		BEGIN
			delete from MISORA..DBMISIMP.SORTAMENTEX where bold_id =@id
			
			FETCH NEXT FROM fetch_cursor 
			INTO @id
		END

	CLOSE fetch_cursor
	  
	DEALLOCATE fetch_cursor 
	
	end;
  

  IF NOT EXISTS(SELECT * FROM DELETED) AND  EXISTS(SELECT * FROM INSERTED)
	insert MISORA..DBMISIMP.SORTAMENTEX([BOLD_ID],[BOLD_TYPE],[OBJECTID],[NAME],[code],[SORTAMENTMATERIAL],[TYPOSIZEVALUE],[OPTIONS])
	select [BOLD_ID],[BOLD_TYPE],[OBJECTID],[NAME],[code],[SORTAMENTMATERIAL],[TYPOSIZEVALUE],[OPTIONS] from INSERTED
 
END


Работает медленно особенно на update.
Подскажите можно ли как-то его модифицировать для ускорения?
21 окт 16, 09:44    [19807223]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Андрей Ч.,

убрать курсоры, прочитать про JOIN
21 окт 16, 09:46    [19807236]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
Андрей Ч.
Member

Откуда: Челябинск
Сообщений: 173
TaPaK, например можно удаление сделать так
delete from MISORA..DBMISIMP.SORTAMENTEX where bold_id
in (select bold_id from deleted)

а как быть с обновлением?
21 окт 16, 09:57    [19807292]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6802
Андрей Ч.,

update	a
set [BOLD_TYPE] = INSERTED.BOLD_TYPE,
[OBJECTID] = INSERTED.OBJECTID,
[NAME] = INSERTED.NAME,
[code] = INSERTED.CODE,
[SORTAMENTMATERIAL] = INSERTED.SORTAMENTMATERIAL,
[TYPOSIZEVALUE] = INSERTED.TYPOSIZEVALUE,
[OPTIONS] = INSERTED.OPTIONS
from INSERTED b	
JOIN  MISORA..DBMISIMP.SORTAMENTEX a
ON
	a.SORTAMENTEX.BOLD_ID = b.BOLD_ID 
21 окт 16, 10:01    [19807328]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31960
Андрей Ч.
TaPaK, например можно удаление сделать так
delete from MISORA..DBMISIMP.SORTAMENTEX where bold_id
in (select bold_id from deleted)
Не надо IN, почитайте про JOIN
21 окт 16, 10:20    [19807468]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
Андрей Ч.
Member

Откуда: Челябинск
Сообщений: 173
alexeyvg, покритикуйте пожалуйста такой код, работает намного быстрее
exec ('update DBMISIMP.SORTAMENTEX 
                        set BOLD_TYPE = ?, 
                        OBJECTID = ?, 
                        NAME = ?, 
                        CODE = ?, 
                        SORTAMENTMATERIAL = ?, 
                        TYPOSIZEVALUE = ?, 
                        OPTIONS = ? 
                        where BOLD_ID = ?', @BOLD_TYPE, @OBJECTID, @NAME,
			@CODE , @SORTAMENTMATERIAL ,
			@TYPOSIZEVALUE , @OPTIONS, @id ) at misora
24 окт 16, 10:06    [19814475]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Андрей Ч.
alexeyvg, покритикуйте пожалуйста такой код, работает намного быстрее
exec ('update DBMISIMP.SORTAMENTEX 
 set BOLD_TYPE = ?, 
 OBJECTID = ?, 
 NAME = ?, 
 CODE = ?, 
 SORTAMENTMATERIAL = ?, 
 TYPOSIZEVALUE = ?, 
 OPTIONS = ? 
 where BOLD_ID = ?', @BOLD_TYPE, @OBJECTID, @NAME,
			@CODE , @SORTAMENTMATERIAL ,
			@TYPOSIZEVALUE , @OPTIONS, @id ) at misora
Это на каком сервере так можно?
результат PRINT @@VERSION покажите, пожалуйста.
24 окт 16, 11:07    [19814714]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
Андрей Ч.
Member

Откуда: Челябинск
Сообщений: 173
iap,
Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 (X64)
Jun 28 2012 08:36:30
Copyright (c) Microsoft Corporation
Express Edition with Advanced Services (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) (Hypervisor)
24 окт 16, 20:58    [19817635]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31960
iap
Это на каком сервере так можно?
Это вы про параметры?
К linked серверу можно. Не к linked серверу почему то нельзя...
24 окт 16, 21:55    [19817752]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с триггером  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31960
Андрей Ч.
update MISORA..DBMISIMP.SORTAMENTEX 
			set [BOLD_TYPE] = INSERTED.BOLD_TYPE,
			[OBJECTID] = INSERTED.OBJECTID,
			[NAME] = INSERTED.NAME,
			[code] = INSERTED.CODE,
			[SORTAMENTMATERIAL] = INSERTED.SORTAMENTMATERIAL,
			[TYPOSIZEVALUE] = INSERTED.TYPOSIZEVALUE,
			[OPTIONS] = INSERTED.OPTIONS
			from INSERTED where SORTAMENTEX.BOLD_ID =@id

Работает медленно особенно на update.

Андрей Ч.
alexeyvg, покритикуйте пожалуйста такой код, работает намного быстрее
exec ('update DBMISIMP.SORTAMENTEX 
 set BOLD_TYPE = ?, 
 OBJECTID = ?, 
 NAME = ?, 
 CODE = ?, 
 SORTAMENTMATERIAL = ?, 
 TYPOSIZEVALUE = ?, 
 OPTIONS = ? 
 where BOLD_ID = ?', @BOLD_TYPE, @OBJECTID, @NAME,
			@CODE , @SORTAMENTMATERIAL ,
			@TYPOSIZEVALUE , @OPTIONS, @id ) at misora

Ну, как минимум во втором варианте вы апдэйтите по одной записи :-)

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

Вот, TaPaK вам написал правильный апдэйт с правильным джойном с INSERTED

Ещё одна тонкость, связанная с Linked Server

Сиквел может делать неоптимальный план, и гонять туда-сюда массивы данных в линкед.

Поэтому я бы сделал 3 варианта , и сравнил:
1) правильный апдэйт с правильным джойном с INSERTED без цикла (как TaPaK написал ).
2) цикл по inserted и exec с параметрами
3) цикл по inserted и update с параметрами
24 окт 16, 22:03    [19817772]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить