Я занимаюсь оптимизацией производительности триггера и хочу протестировать ее. У меня есть фактический триггер и модифицированный триггер, и я хочу на реальных данных запустить тест на старом триггере и новом триггере и сравнить их. Я хочу скопировать таблицу A в A_BCK построчно. В таблице A около 60 столбцов и 4000 строк, поэтому мой триггер будет выполняться 4000 раз, и я могу использовать его для теста производительности.
Я читал о курсорах, но не могу понять, как использовать курсор и переменную для копирования строки за строкой (не выбирать в a_bck или вставлять в a_bck, выбирать из a, которые оба генерируют только одну вставку).
Моя процедура копирования строк на данный момент выглядит так:
declare @actualrow varchar(15);
DECLARE eoauz CURSOR FAST_FORWARD FOR SELECT * FROM A
open eoauz
fetch next from eoauz into @actualrow
while @@fetch_status = 0
begin
/* INSERT INTO A_BCK VALUES FROM @actualrow */
fetch next from eoauz into @actualrow
end
close eoauz
deallocate eoauz
Конечно, это не работает. Мне нужно что-то вроде переменной строки вместо varchar. Может кто-нибудь помочь, как выполнить мою задачу?
Ответ 1 · рейтинг 4 · Martin Smith
Я не часто работаю с курсорами, поэтому может быть более простой способ, который мне не хватает...
SELECT TOP 0 *
INTO #t
FROM master..spt_values /*Create an empty table of correct schema*/
DECLARE eoauz CURSOR FAST_FORWARD FOR
SELECT *
FROM master..spt_values
OPEN eoauz
INSERT INTO #t
EXEC ('fetch next from eoauz')
WHILE @@FETCH_STATUS = 0
INSERT INTO #t
EXEC ('fetch next from eoauz')
CLOSE eoauz
DEALLOCATE eoauz
SELECT *
FROM #t
DROP TABLE #t
Ответ 2 · рейтинг 2 · RichardTheKiwi
Пример таблицы для кода ниже
create table A(ID INT IDENTITY, a int, b int)
create table B(ID INT, a int, b int)
insert A select 1,2 union all select 3,4 union all select 5,6
Вам нужна переменная для каждого столбца. См. пример ниже
declare @id int, @a int, @b int
DECLARE eoauz CURSOR FAST_FORWARD FOR SELECT * FROM A
open eoauz
fetch next from eoauz into @id, @a, @b
while @@fetch_status = 0
begin
INSERT B VALUES( @id, @a, @b )
fetch next from eoauz into @id, @a, @b
end
close eoauz
deallocate eoauz
Я предпочитаю не использовать курсоры и по возможности использовать циклы WHILE.
declare @id int
select top 1 @id = id from A order by ID
while @@ROWCOUNT > 0 begin
insert B select * from A where ID=@id -- one row
select top 1 @id = id from A where id > @id order by ID
end
Ответ 3 · dataduck
Я бы выбрал первичный ключ вашей таблицы в переменную курсора. Это однозначно идентифицирует одну строку, которую затем можно легко выбрать:
declare @pk varchar(15);
DECLARE eoauz CURSOR FAST_FORWARD FOR SELECT PK FROM A
open eoauz
fetch next from eoauz into pk
while @@fetch_status = 0
begin
INSERT INTO A_BCK select * from A where PK = @pk
fetch next from eoauz into pk
end
close eoauz
deallocate eoauz
Я думаю, что этот метод имеет большое преимущество в том, что его легко понять и прочитать.