Я поддерживаю некоторый код, который имеет триггер для таблицы для увеличения столбца.Этот столбец затем используется сторонним приложением A .Допустим, таблица называется test с двумя столбцами num1 и num2 .Триггер запускается при каждой вставке num1 в test .Ниже приведен триггер:
USE [db1]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[TEST_MYTRIG] ON [dbo].[test]
FOR INSERT AS
begin
SET NOCOUNT ON
DECLARE @PROC_NEWNUM1 VARCHAR (10)
DECLARE @NEWNUM2 numeric(20)
SELECT @PROC_NEWNUM1 = num1 FROM INSERTED
select @NEWNUM2 = MAX(num2) from TEST
if @NEWNUM2 is null
Begin
set @NEWNUM2 = 0
end
set @NEWNUM2 = @NEWNUM2 + 1
UPDATE TEST SET num2 = @NEWNUM2 WHERE num1 = @PROC_NEWNUM1
SET NOCOUNT OFF
End
Это прекрасно работает при простых вставках на основе строк, но есть другое стороннее приложение B (вздох), которое иногда выполняет несколько вставок в эту таблицу, что-то вродеэто, но не совсем так:
INSERT INTO [db1].[dbo].[test]
([num1])
Select db1.dbo.test.num1 from [db1].[dbo].[test]
GO
Это приводит к тому, что триггер работает некорректно ...
Теперь у меня нет доступа к источнику приложения A или B и управлять только базой данных и триггером.Есть ли что-нибудь, что можно сделать с помощью триггера, чтобы обновления, сделанные для num2 , были правильными в случае нескольких вставок?
Решение:
Ниже приводится решение, основанное на коде аффана:
DECLARE @PROC_NEWNUM1 VARCHAR (10)
DECLARE @NEWNUM2 numeric(20)
DECLARE my_Cursor CURSOR FAST_FORWARD FOR SELECT num1 FROM INSERTED;
OPEN my_Cursor
FETCH NEXT FROM my_Cursor into @PROC_NEWNUM1
WHILE @@FETCH_STATUS = 0
BEGIN
select @NEWNUM2 = MAX(num2) from TEST
if @NEWNUM2 is null
Begin
set @NEWNUM2 = 0
End
set @NEWNUM2 = @NEWNUM2 + 1
UPDATE TEST SET num2 = @NEWNUM2 WHERE num1 = @PROC_NEWNUM1
FETCH NEXT FROM my_Cursor into @PROC_NEWNUM1
END
CLOSE my_Cursor
DEALLOCATE my_Cursor
Проверьте здесь подход на основе множеств: SQL Server - триггер перезаписи, чтобы избежать подхода на основе курсора