2011-01-28 3 views
3

Я выполняю оптимизацию производительности триггера, и я хочу ее протестировать. У меня есть фактический триггер и измененный триггер, и я хочу, чтобы реальные данные запускали тест на старом триггере и новом триггере и сравнивали его. Я хочу скопировать таблицу A в A_BCK по строкам. Таблица A содержит около 60 столбцов и 4000 строк, поэтому мой триггер будет выполняться 4000 раз, и я могу использовать его для теста производительности.Копировать таблицу по строкам

Я читал о курсорах, но не могу понять, как использовать курсор и переменную для копирования строк за строкой (не выбирать в a_bck или вставлять в a_bck выбор, из которого оба генерируют только одну вставку).

Моя строка процедура копирования, как на данный момент выглядит следующим образом:

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. Может кто-то помочь, как выполнить мою задачу?

+2

Почему это происходит по строкам? MSSQL устанавливается на основе. Избегайте использования курсоров, особенно в триггерах - если вам не нравится жить в мире боли. – codingbadger

+0

Я не делаю этого _in_ моего триггера. Я хочу сделать это для _test_ моего триггера. Мне нужен способ выполнить мой триггер на реальных данных. –

+0

Хмм, если вы удаляете бит 'in @ actualrow', он возвращает всю строку обратно клиенту. Я не уверен, есть ли синтаксис, чтобы как-то вставить эту строку в другую таблицу. –

ответ

1

Пример таблицы для кода ниже

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 [email protected] -- one row 
    select top 1 @id = id from A where id > @id order by ID 
end 
+0

Спасибо за ответ. Мне не нравится, что у меня 60 столбцов, поэтому я должен объявить 60 переменных. Кроме того, я хочу, чтобы курсор использовался только для тестирования. У меня нет курсоров в производственной БД. Так что действительно, у парней нет страха, что я буду использовать его в производстве ;-) –

+0

@Robert - см. Альтернативу цикла (который также может работать на курсоре), используя один столбец (ключ), чтобы вернуться к таблице – RichardTheKiwi

+0

, хотя выглядит действительно хорошо, im попробовать это сейчас –

4

Я не часто работаю с курсорами, так что может быть более простым способом я пропавший без вести ...

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 
+0

Какая жалость. Я перепутал с голосованием и больше не могу выдвигать этот ответ. То, что я сделал, я поддержал это, а затем быстро вызвал мой голос, чтобы проверить сначала, работает ли этот метод. И это было. Теперь я пытаюсь перевернуть его снова, но он продолжает говорить, что мой голос теперь заблокирован, пока не будет отредактирован ответ. Неужели это так упрямо? Ваш ответ, похоже, не нуждается в какой-либо существенной модификации, если вы не захотите добавить почти бессмысленный 'select * from # t' в конце (ваш пример - просто тест в любом случае). В противном случае, это моя мысль. Таким образом, ожидаемый аванс не ожидается. –

+0

@Andriy - Спасибо! Я сделал предложенное изменение. –

+0

И идет +1. (* в сторону *) Интересно, является ли эта проблема блога в случае, если это проблема или функция ... –

0

Я бы выбрал первичный ключ вашей таблицы в вашей переменной курсора. Это однозначно идентифицирует одну строку, которую вы можете легко выбрать:

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 

Я думаю, что этот метод имеет большое преимущество в том, легко понять и прочитать.

Смежные вопросы