Nossos desenvolvedores têm usado um cursor em um procedimento armazenado para excluir o histórico de senhas antigas. O número de registros a serem excluídos está sendo passado por variável.
DECLARE hist_cursor CURSOR LOCAL FOR
SELECT history_nr FROM usr_pwd_hist WHERE usr_id = @usr_id
ORDER BY history_nr ASC
OPEN hist_cursor
WHILE @to_delete > 0
BEGIN
FETCH NEXT FROM hist_cursor INTO @hist_val
DELETE FROM usr_pwd_hist WHERE CURRENT OF hist_cursor
SET @to_delete = @to_delete-1
END
CLOSE hist_cursor;
DEALLOCATE hist_cursor;
Eu gostaria de substituir isso por uma abordagem baseada em conjunto. Não posso fazer uma instrução superior simples porque o número de registros a serem excluídos é uma variável. Não consigo usar um top com uma variável sem sql dinâmico e por política não permitimos sql dinâmico em produção.
Estou considerando esta abordagem abaixo, mas isso me deixa nervoso, pois sei que a Microsoft está planejando mudar a maneira como ROWCOUNT afeta os resultados de retorno . Ao colocar os destinos de exclusão em uma subconsulta, devo estar de acordo com as versões futuras do SQL, mas ainda estou me perguntando se existe uma maneira melhor de excluir um número variável de registros por ordem cronológica.
SET ROWCOUNT @to_delete; /* limit records to be deleted */
DELETE FROM usr_pwd_hist WHERE history_nr IN
(
SELECT history_nr
FROM usr_pwd_hist
WHERE usr_id = @usr_id
ORDER BY history_nr ASC
);
SET ROWCOUNT 0; /* return rowcount to default setting */
Você pode usar
TOP
com uma variável. Você só precisa colocar entre parênteses.