SQL для цикла с использованием идентификаторов, возвращаемых в операторе Select - PullRequest
1 голос
/ 05 января 2012

Мне нужно удалить несколько строк из моей базы данных при определенных условиях. У меня есть оператор select для возврата этого условия, а затем для каждой строки в этом операторе select мне нужно выполнить SP, который удалит эти строки и загрузку связанных строк. Пока что у меня есть:

select importfileid from import.importfiles where importfilestatusid < 7

и затем выполнить

EXEC    [import].[spDeleteFromAllImportRelatedTables]
    @fileID = @importfileid

Я просто не уверен, как сделать промежуточное звено? Если бы кто-то мог указать мне правильное направление, это было бы здорово.

NB: Это разовая вещь. Производительность не проблема.

Ответы [ 5 ]

2 голосов
/ 05 января 2012

Вы можете использовать курсор:

declare @importFileID int
declare @cur cursor

set @cur = cursor fast_forward for 
select importfileid from import.importfiles where importfilestatusid < 7

open @cur
fetch next from @cur into @importFileID
while(@@fetch_status = 0)
begin
  exec [import].[spDeleteFromAllImportRelatedTables] @fileID = @importFileID
  fetch next from @cur into @importFileID
end
close @cur
deallocate @cur
1 голос
/ 05 января 2012

Попробуйте использовать курсор на выбор. Посмотрите в этой ссылке http://msdn.microsoft.com/en-us/library/ms180169.aspx

0 голосов
/ 05 января 2012

У вас есть несколько вариантов, ни один из которых не является красивым.

Использовать курсор

С помощью курсора (fastforward readonly) вы можете циклически перебирать результаты и вызывать хранимую процедуру.


Удерживающий стол

Вставьте все записи в таблицу, затем запишите хранимую процедуру для чтения из этой таблицы.

Это может быть реальная таблица или # временная таблица.

Это имеет преимущество в том, что вы можете выполнять все удаления вместе, а не в итерационном цикле.


Инкапсулировать первый шаг в функции

Если вы поместите свой код SELECT в функцию, вы можете перекодировать SP, чтобы вызвать эту функцию, чтобы найти записи, которые нужно удалить. Параметры SP затем становятся такими же, как параметры функции.


Это несколько исправлено в SQL Server 2008+ с параметрами таблицы. Но не в SQL Server 2005.

0 голосов
/ 05 января 2012

Я никогда не буду предлагать использовать курсор, лучше перейдите на подход, основанный на SET. если возможно, вы можете использовать соединения во всех относительных таблицах, чтобы удалить все эти строки. Это было бы быстрее подход. Создайте одного SP и создайте одно задание, которое делает это для вас через определенный промежуток времени, жизнь будет легкой.

0 голосов
/ 05 января 2012

Я предполагаю, что SP делает что-то более особенное, чем просто удаление строки.

Если это единственная вещь, вы могли бы просто сделать что-то хакерское, например:

SELECT 'EXEC    [import].[spDeleteFromAllImportRelatedTables]    @fileID =',  importfileid from import.importfiles where importfilestatusid < 7

И затемскопируйте и вставьте результаты и выполните это?

Альтернативно, если это запланированная очистка, подумайте о переосмыслении вашего кода и написании нового SP, который выполняет то же, что и DeleteFromAllImportRelatedTables, но с использованием критериев, указанных вами выше.Хотя, возможно, имеется некоторое дублирование кода, это, скорее всего, сделает его более быстрым и легким для понимания того, что происходит, и будет легче отлаживать, так как вы не будете отслеживать вызовы SP внутри SP, чтобы найти какие-либо проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...