У меня есть таблица с чуть более 1 миллиона записей. Первоначально моя таблица пуста, но я использую BULK INSERT
для добавления этих записей в базу данных. У меня есть AFTER INSERT
триггер, который я использую для обновления поля initialValue
в этой таблице. Значение initialValue
является вычислением конкретных переменных в другой таблице (my_data_db
), суммируемых по всем записям. В качестве имен столбцов в таблице my_data_db
.
я использую значения столбцов
v1
,
v2
и т. Д.
Я знаю, что это плохая практика, но единственный способ, которым я в настоящее время знаю, как сделать это вычисление для каждой отдельной строки, это использовать курсор. Очевидно, что с миллионами записей это действительно очень медленно.
Вот пример таблицы, на которой у меня есть триггер:
TABLE: test3
rowID v1 v2 v3 combo initialValue
1 NULL M170_3 M170_4 C NULL
2 M170_2 M170_3 M170_4 ABC NULL
3 M170_2 M170_3 NULL AB NULL
...
Мой триггер:
CREATE TRIGGER [dbo].[trig_UPDATE_test3]
ON [dbo].[test3]
AFTER INSERT
AS
Begin
DECLARE @sql VARCHAR(MAX)
DECLARE @v1 VARCHAR(20)
DECLARE @v2 VARCHAR(20)
DECLARE @v3 VARCHAR(20)
DECLARE @combo VARCHAR(30)
DECLARE mycursor CURSOR FOR
SELECT v1, v2, v3, combo
FROM Inserted
OPEN mycursor
FETCH NEXT FROM mycursor INTO @v1, @v2, @v3, @combo
WHILE @@FETCH_STATUS = 0
BEGIN
IF( @v1 IS NOT NULL OR @v2 IS NOT NULL OR @v3 IS NOT NULL)
BEGIN
SET @sql = 'DECLARE @finalValue DECIMAL(18, 15);'
SET @sql = @sql + 'UPDATE test3 Set initialValue = (SELECT CAST(SUM('
IF(@v1 IS NOT NULL)
BEGIN
SET @sql = @sql + 'CASE ' + @v1 + ' WHEN 1 THEN 1 WHEN 2 THEN .75 WHEN 3 THEN .25 WHEN 4 THEN .1 END * '
END
IF(@v2 IS NOT NULL)
BEGIN
SET @sql = @sql + 'CASE ' + @v2 + ' WHEN 1 THEN 1 WHEN 2 THEN .75 WHEN 3 THEN .25 WHEN 4 THEN .1 END * '
END
IF(@v3 IS NOT NULL)
BEGIN
SET @sql = @sql + 'CASE ' + @v3 + ' WHEN 1 THEN 1 WHEN 2 THEN .75 WHEN 3 THEN .25 WHEN 4 THEN .1 END * '
END
SET @sql = @sql + 'RESP_WEIGHT / 4898.947426) AS FLOAT) FROM dbo.my_data_db) WHERE combo = ''' + @combo + ''';'
EXECUTE(@sql)
END
FETCH NEXT FROM mycursor INTO @v1, @v2, @v3, @combo
END
CLOSE mycursor
DEALLOCATE mycursor
End
После запуска триггера моя таблица test3
будет выглядеть примерно так:
TABLE: test3
rowID v1 v2 v3 combo initialValue
1 NULL M170_3 M170_4 C 0.138529
2 M170_2 M170_3 M170_4 ABC 0.683190
3 M170_2 M170_3 NULL AB 0.014923
...
Есть ли способ, которым я могу сделать это без использования курсора?