Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Использовать ли тригер? (число прочтений - 3367 )
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Использовать ли тригер?
25. Июня 2009 :: 07:34
Печать  
Есть БД, в ней (условно) хранимая процедура и две таблицы (А,Б). Стороннее приложение пишет в таблицу - А через эту хранимку. На основе записываемых/обновляемых данных надо заполнять вторую табличку - В. Вариантов 2:
1 - Тригер на таблицу и формирование второй таблицы данными тригера
2 - Формирование таблицы сразу же в хранимке.

Будет небольшой расчет прежде чем писать таблицу Б.
Вопросы:
1. Что выгоднее тригер или сразу из хранимки? В плане того, что хранимая процедура будет замедлятся расчетами для таблицы Б - чего бы не очень хотелось.
2. Будет ли успевать тригер производить расчеты на вставку в таблицу Б, если скорость его работы будет явно медленнее работы хранимки?

зы. Да и так чисто на пальцах, как срабатывает тригер? После каждого INSERT/UPDATE/DELET или как то буферизирует данные?
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Использовать ли тригер?
Ответ #1 - 25. Июня 2009 :: 08:10
Печать  
ихмо хранимка
для нее создается оптимальный план выполнения который и
выполняется.

Тригер нужен когда данные модифицируют из  разных мест,
а у тебя этого нет по условию задачи.
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #2 - 25. Июня 2009 :: 08:16
Печать  
Ясно, спасиб. Значит будем из хранимки. Данные действительно модифицируются только через нее.
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #3 - 25. Июня 2009 :: 09:05
Печать  
Новую тему заводить не буду... Помогите доработать запрос:
INSERT INTO Change (Cash,Type,d1,d2,do)
     (SELECT c.id,'Article',@ID,NULL,0 FROM Cash AS c WHERE c.IsDel=0 AND c.mode = 2)

Надо условие, на то, что такой записи еще нет, что бы дубли не писать...
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Использовать ли тригер?
Ответ #4 - 25. Июня 2009 :: 09:20
Печать  
zenik писал(а) 25. Июня 2009 :: 09:05:
Новую тему заводить не буду... Помогите доработать запрос:
INSERT INTO Change (Cash,Type,d1,d2,do)
     (SELECT c.id,'Article',@ID,NULL,0 FROM Cash AS c WHERE c.IsDel=0 AND c.mode = 2)

Надо условие, на то, что такой записи еще нет, что бы дубли не писать...

IF EXISTS(  SELECT c.id  FROM Cash AS c WHERE c.IsDel=0 AND c.mode = 2)
INSERT INTO Change (Cash,Type,d1,d2,do)
values(...)

Если на повторяющихся данных есть кластерный индекс то можно просто выставить флаг  на таблице игнорировать дубли при вставке.
Этот способ теоретически быстрее но на 1с таблицах его лучше не использовать.


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


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #5 - 25. Июня 2009 :: 09:38
Печать  
Неееееееееее.... Так бы я и сам придумал Улыбка Не нравится мне 2 раза селект дергать один и тот же. Думаю через хранимую процедуру сделать... Только как ее вызывать и передавать параметры?
Или объявить переменные, и туда их, потом уже через переменные условия и вставка. Но опять же как...
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Использовать ли тригер?
Ответ #6 - 25. Июня 2009 :: 10:09
Печать  
Код
Выбрать все
INSERT INTO Change (Cash,Type,d1,d2,do)
values(c_1.id,'Article',@ID,NULL,0)
   select * from Change as c_1
   where not exists(c_1.IsDel=0 AND c_1.mode = 2 and c_1.d1 = @ID )
 



Идея правильная. Только может не все твои поля правильно написал
т.к. не знаю точно их назначения
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #7 - 25. Июня 2009 :: 10:20
Печать  
Ага, понял. Спасиб.

Вопрос в догонку. Сделал все таки еще одну хранимку и вызвал через нее:

EXEC UpdateChange (SELECT c.id,'Article',@ID,NULL FROM Cash AS c WHERE c.IsDel=0 AND c.mode = 2)

И сама ХП (урезаный вариант):

PROCEDURE [dbo].[UpdateChange] (
     @Cash numeric(6,0),
     @Type varchar(100),
     @D1 varchar(100),
     @D2 varchar(100)
)

IF NOT EXISTS (SELECT * FROM Change WHERE Cash = @Cash AND Type = @Type AND D1 = @D1 AND D2 = @D2)
     INSERT Change VALUES (@Cash,@Type,@D1,@D2,0)

Но почему то, если @D2 = NULL Select в условии дает пустую выборку и соответственно запись вставляется...
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #8 - 25. Июня 2009 :: 10:27
Печать  
Z1 писал(а) 25. Июня 2009 :: 10:09:
Код
Выбрать все
INSERT INTO Change (Cash,Type,d1,d2,do)
values(c_1.id,'Article',@ID,NULL,0)
   select * from Change as c_1
   where not exists(c_1.IsDel=0 AND c_1.mode = 2 and c_1.d1 = @ID )
 



Идея правильная. Только может не все твои поля правильно написал
т.к. не знаю точно их назначения


Не работает Печаль

Код
Выбрать все
INSERT INTO Change (Cash,Type,d1,d2,do)
VALUES(c.id,'Article',@ID,NULL,0)
   SELECT * FROM Change as C
   WHERE NOT EXISTS( C.IsDel = 0 AND C.mode = 2 AND C.d1 = @ID ) 



Цитата:
Сообщение 128, уровень 15, состояние 1, строка 2
The name 'id' is not permitted in this context. Only constants, expressions, or variables allowed here. Column names are not permitted.
Сообщение 170, уровень 15, состояние 1, строка 4
Line 4: Incorrect syntax near 'C'.


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


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #9 - 25. Июня 2009 :: 10:42
Печать  
Такс, ну почему не срабатывает select - проникся. D2 = null должно быть как D2 IS NULL... Но он же может и не быть null. D1 тоже может быть null. Хочется универсальности.
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #10 - 25. Июня 2009 :: 10:53
Печать  
Только вот такая этажерка спасла отца русской демократии:
Код
Выбрать все
IF @D2 IS NULL
	IF @D1 IS NULL
		BEGIN
			IF NOT EXISTS (SELECT * FROM Change WHERE Cash = @Cash AND Type = @Type AND D1 IS NULL AND D2 IS NULL)
				INSERT Change VALUES (@Cash,@Type,@D1,@D2,0)
		END
	ELSE
		BEGIN
			IF NOT EXISTS (SELECT * FROM Change WHERE Cash = @Cash AND Type = @Type AND D1 = @D1 AND D2 IS NULL)
				INSERT Change VALUES (@Cash,@Type,@D1,@D2,0)
		END
ELSE
	IF NOT EXISTS (SELECT * FROM Change WHERE Cash = @Cash AND Type = @Type AND D1 = @D1 AND D2 = @D2)
		INSERT Change VALUES (@Cash,@Type,@D1,@D2,0)
 


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


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Использовать ли тригер?
Ответ #11 - 25. Июня 2009 :: 11:09
Печать  
а может default значения назначить ?
или
в VALUES( expression )
а expression использует ISNULL()
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #12 - 25. Июня 2009 :: 11:14
Печать  
Если можно поподробней... Не понял ничего   Озадачен
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Использовать ли тригер?
Ответ #13 - 25. Июня 2009 :: 11:20
Печать  
Код
Выбрать все
INSERT Change VALUES ( ISNULL(@D1,100))
 


Т.е если @D1 = NULL вставляем 100
Только есть тонкость типы у @D1 и 100 должны быть одинаковые
  
Наверх
 
IP записан
 
zenik
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 109
Зарегистрирован: 09. Октября 2007
Re: Использовать ли тригер?
Ответ #14 - 25. Июня 2009 :: 11:32
Печать  
Не... Потом из этой таблицы еще и данные выбирать. Всего потом не учтешь.
Тут еще хитрее ситуация.
Если вызываю EXEC UpdateChange 1,1,1,1 - гут, все красиво отрабатывает. А вот если ее вызывает ХП:
Код
Выбрать все
EXEC UpdateChange (SELECT c.id,'Article',@ID,NULL FROM Cash AS c WHERE c.IsDel=0 AND c.mode = 2) 


Тогда
Цитата:
Сообщение 201, уровень 16, состояние 3, процедура UpdateChange, строка 0
Procedure 'UpdateChange' expects parameter '@Cash', which was not supplied.


ХП выглядит так:
Код
Выбрать все
ALTER PROCEDURE [dbo].[UpdateChange] (
	@Cash numeric(6,0),
	@Type varchar(100),
	@D1 varchar(100),
	@D2 varchar(100)
)
AS
BEGIN

IF @D2 IS NULL
	IF @D1 IS NULL
		BEGIN
			IF NOT EXISTS (SELECT * FROM Change WHERE Cash = @Cash AND Type = @Type AND D1 IS NULL AND D2 IS NULL)
				INSERT Change VALUES (@Cash,@Type,@D1,@D2,0)
		END
	ELSE
		BEGIN
			IF NOT EXISTS (SELECT * FROM Change WHERE Cash = @Cash AND Type = @Type AND D1 = @D1 AND D2 IS NULL)
				INSERT Change VALUES (@Cash,@Type,@D1,@D2,0)
		END
ELSE
	IF NOT EXISTS (SELECT * FROM Change WHERE Cash = @Cash AND Type = @Type AND D1 = @D1 AND D2 = @D2)
		INSERT Change VALUES (@Cash,@Type,@D1,@D2,0)
END 



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