powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Есть-ли альтернатива ЭТОТМУ триггеру ?
11 сообщений из 11, страница 1 из 1
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32066727
gevst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть две таблицы : nach_abon(суммы) и d_itog(итоги по суммам), необходимо на основе первой формировать суммы во второй таблице.. Написал триггер, использующий курсор, можно ли это решить как то по другому ?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
CREATE TRIGGER NACH_ABON_INSERT
ON dbo.NACH_ABON
for insert AS
	declare @ID bigint
	declare @sum money
	declare Cur_ins cursor for select id_klient, sum_nach_abon from inserted
		
open cur_ins
		fetch cur_ins
		into @ID, @SUM
	While @@Fetch_status= 0 
	Begin
	if not exists (select * from d_itog where id_klient=@id)
	begin	
		insert into d_itog (Id_klient, sum_itog) 
		select @id, -@sum, 1 
		fetch cur_ins
		into @ID, @SUM
	end
	if exists (select * from d_itog where id_klient=@id)
	begin
		update d_itog
		set sum_itog = sum_itog - @sum
		from d_itog
		where id_klient=@id
	end
	end
Close Cur_ins
deallocate Cur_ins
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32066737
Denis@nk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне кажется в таблице inserted всегда 1 запись.
Поэтому курсором можно не пользоваться.
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32066739
gevst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Denis@nk в том то и дело что нет.. запрос на заливку, например..
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32066786
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CREATE TRIGGER NACH_ABON_INSERT
ON dbo.NACH_ABON
for insert AS

insert d_itog (Id_klient, sum_itog) 
select a.id_klient,  0  from inserted a
left outer join d_itog b on b.Id_klient = a.id_klient
where b.Id_klient is null

update a set sum_itog = a.sum_itog - b.sum_nach_abon 
from d_itog a
inner join inserted b on b.Id_klient = a.id_klient


Не понял только как в этом запросе
insert into d_itog (Id_klient, sum_itog) select @id, -@sum, 1
вы добавляете 3 поля ?
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32066993
gevst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Glory огромное спасибо за помощь начинающему :)
А насчет добавления, просто опечатался, применил предложеный тобой подход и все прекрасно, единственно думаю добавить проверку на кол-во записейи ввести переменные, чтобы не просматривать все записи при одиночных вставках.
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32067024
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
думаю добавить проверку на кол-во записейи ввести переменные, чтобы не просматривать все записи при одиночных вставках

Это вы про какие такие "просмотры всех записей" ведете речь ?
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32067219
gevst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Glory в смысле if @@rowcount>1 тогда заливать, а так по одиночке :)
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32067257
Flint-San
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CREATE TABLE NACH_ABON
(
id1 bigint Identity(0,1) PRIMARY KEY,
id_klient bigint,
sum_nach_abon money
)
GO

CREATE TABLE d_itog
(
Id_klient bigint PRIMARY KEY,
sum_itog money
)
GO


CREATE TRIGGER NACH_ABON_INSERT
ON dbo.NACH_ABON
for insert AS

Declare @ErrStr varchar(255)

SET NOCOUNT ON

UPDATE U
SET sum_itog = U.sum_itog + (SELECT Sum(X.sum_nach_abon) FROM INSERTED AS X WHERE X.id_klient=U.id_klient)
FROM
INSERTED AS I
INNER JOIN d_itog AS U ON U.id_klient=I.id_klient

IF @@ERROR <> 0
BEGIN
SET @ErrStr = 'Ошибка! Перерасчета итоговых сумм!'
GOTO Err_NACH_ABON_INSERT_Ins
END

INSERT d_itog(Id_klient,sum_itog)
SELECT
id_klient, Sum(I.sum_nach_abon)
FROM
INSERTED AS I
WHERE
0=(Select count(X.id_klient) From d_itog AS X WHERE X.id_klient=I.id_klient)
GROUP BY id_klient

IF @@ERROR <> 0
BEGIN
SET @ErrStr = 'Ошибка! Расчета итоговой суммы!'
GOTO Err_NACH_ABON_INSERT_Ins
END

SET NOCOUNT OFF
return

Err_NACH_ABON_INSERT_Ins:
ROLLBACK TRANSACTION
RAISERROR (@ErrStr,16,-1)
GO

SELECT id_klient,sum_nach_abon INTO #Temp FROM NACH_ABON WHERE 0=1

INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(1,50)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(1,20)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(1,40)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(2,30)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(2,0)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(5,10)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(1000,100)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(1000,-50)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(1000,400)
INSERT INTO #Temp(id_klient,sum_nach_abon) VALUES(1000,200)
INSERT INTO NACH_ABON(id_klient,sum_nach_abon)
SELECT id_klient,sum_nach_abon FROM #Temp

DROP TABLE #Temp
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32067282
gevst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Flint-San выражаю горячую благодарность !!!
Добавил еще один параметр выборки кроме id выполнено 250000 записей за 30 сек без ошибки !
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32067289
Flint-San
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот подумалось, а почему trigger только на Insert?
В задаче наверняка требуются делать все операции.
Поэтому предагаю заменить предыдущий trigger следующим:
CREATE TRIGGER NACH_ABON_INSUPDDEL
ON dbo.NACH_ABON
for insert,update,delete AS

Declare @ErrStr varchar(255)

SET NOCOUNT ON

DELETE FROM X
FROM
d_itog AS X
INNER JOIN DELETED AS D ON X.id_klient=D.id_klient
WHERE
0=(SELECT count(I.id_klient) FROM INSERTED AS I WHERE I.id_klient=D.id_klient)
AND 0=(SELECT count(A.id_klient) FROM NACH_ABON AS A WHERE A.id_klient=D.id_klient)

IF @@ERROR <> 0
BEGIN
SET @ErrStr = 'Ошибка! Удаления иговых сумм для несуществующих клиентов!'
GOTO Err_NACH_ABON_INSUPDDEL
END

UPDATE U
SET sum_itog = U.sum_itog - (SELECT Sum(X.sum_nach_abon) FROM DELETED AS X WHERE X.id_klient=U.id_klient)
FROM
DELETED AS D
INNER JOIN d_itog AS U ON U.id_klient=D.id_klient

IF @@ERROR <> 0
BEGIN
SET @ErrStr = 'Ошибка! Перерасчета итоговых сумм1!'
GOTO Err_NACH_ABON_INSUPDDEL
END

UPDATE U
SET sum_itog = U.sum_itog + (SELECT Sum(X.sum_nach_abon) FROM INSERTED AS X WHERE X.id_klient=U.id_klient)
FROM
INSERTED AS I
INNER JOIN d_itog AS U ON U.id_klient=I.id_klient

IF @@ERROR <> 0
BEGIN
SET @ErrStr = 'Ошибка! Перерасчета итоговых сумм2!'
GOTO Err_NACH_ABON_INSUPDDEL
END

INSERT d_itog(Id_klient,sum_itog)
SELECT
id_klient, Sum(I.sum_nach_abon)
FROM
INSERTED AS I
WHERE
0=(Select count(X.id_klient) From d_itog AS X WHERE X.id_klient=I.id_klient)
GROUP BY id_klient

IF @@ERROR <> 0
BEGIN
SET @ErrStr = 'Ошибка! Расчета итоговой суммы!'
GOTO Err_NACH_ABON_INSUPDDEL
END



SET NOCOUNT OFF
return

Err_NACH_ABON_INSUPDDEL:
ROLLBACK TRANSACTION
RAISERROR (@ErrStr,16,-1)
GO

select * from NACH_ABON
select * from d_itog

UPDATE NACH_ABON SET id_klient=5 WHERE id_klient=1
select * from NACH_ABON
select * from d_itog

DELETE FROM NACH_ABON where id_klient=2 or id_klient=1000
select * from NACH_ABON
select * from d_itog
...
Рейтинг: 0 / 0
Есть-ли альтернатива ЭТОТМУ триггеру ?
    #32068777
gevst
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Flint-San триггер работает прекрасно :) Спасибо за помощь ! Буду разбивать его на три части - for insert, update, delete, думаю так он будет работать быстрее :)
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Есть-ли альтернатива ЭТОТМУ триггеру ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]