Digamos que tenho a seguinte variável de tabela simples:
declare @databases table
(
DatabaseID int,
Name varchar(15),
Server varchar(15)
)
-- insert a bunch rows into @databases
Declarar e usar um cursor é minha única opção se eu quiser percorrer as linhas? Existe outro caminho?
sql-server
tsql
loops
Raio
fonte
fonte
STATIC
opção para remover a constante checagem das tabelas de base e os bloqueios existentes por padrão e fazer com que a maioria das pessoas acredite erroneamente que os CURSORES são maus. @ JacquesB muito perto: verificar novamente se a linha de resultados ainda existe + travar são os problemas. ESTATIC
geralmente corrige isso :-).Respostas:
Antes de tudo, você deve ter certeza absoluta de que precisa iterar através de cada operação baseada em conjunto de linhas, que terá um desempenho mais rápido em todos os casos em que eu possa pensar e normalmente usará um código mais simples.
Dependendo dos seus dados, pode ser possível fazer um loop usando apenas as
SELECT
instruções, como mostrado abaixo:Outra alternativa é usar uma tabela temporária:
A opção que você deve escolher realmente depende da estrutura e do volume dos seus dados.
Nota: Se você estiver usando o SQL Server, seria melhor atendido usando:
O uso
COUNT
terá que tocar em todas as linhas da tabela,EXISTS
basta tocar na primeira (veja a resposta de Josef abaixo).fonte
STATIC
opção que copia o conjunto de resultados em uma tabela temporária e, portanto, não está mais bloqueando ou verificando novamente as tabelas base :-).Apenas uma observação rápida, se você estiver usando o SQL Server (2008 e superior), os exemplos que possuem:
Seria melhor servido com
O Conde terá que tocar em todas as linhas da tabela,
EXISTS
basta tocar na primeira.fonte
É assim que eu faço:
Sem cursores, sem tabelas temporárias, sem colunas extras. A coluna USERID deve ser um número inteiro exclusivo, como a maioria das Chaves Primárias.
fonte
Defina sua tabela temporária assim -
Então faça isso -
fonte
Aqui está como eu faria isso:
[Editar] Como provavelmente pulei a palavra "variável" quando li a pergunta pela primeira vez, aqui está uma resposta atualizada ...
fonte
Se você não tem escolha a não ser ir linha por linha, criando um cursor FAST_FORWARD. Será tão rápido quanto criar um loop while e muito mais fácil de manter a longo prazo.
FAST_FORWARD Especifica um cursor FORWARD_ONLY, READ_ONLY com as otimizações de desempenho ativadas. FAST_FORWARD não pode ser especificado se SCROLL ou FOR_UPDATE também estiver especificado.
fonte
FAST_FORWARD
cursor é uma boa solução. (upvote)Outra abordagem sem precisar alterar seu esquema ou usar tabelas temporárias:
fonte
Você pode usar um loop while:
fonte
Isso funcionará na versão SQL SERVER 2012.
fonte
Leve, sem precisar criar tabelas extras, se você tiver um número inteiro
ID
na tabelafonte
fonte
Realmente não vejo o motivo pelo qual você precisaria recorrer ao temido
cursor
. Mas aqui está outra opção se você estiver usando o SQL Server versão 2005/2008Use Recursion
fonte
Vou fornecer a solução baseada em conjunto.
Isso é muito mais rápido do que qualquer técnica em loop e é mais fácil de escrever e manter.
fonte
Prefiro usar a Busca por deslocamento, se você tiver um ID exclusivo, poderá ordenar sua tabela por:
Dessa forma, não preciso adicionar campos à tabela nem usar uma função de janela.
fonte
É possível usar um cursor para fazer isso:
função create [dbo] .f_teste_loop retorna a tabela @tabela (cod int, nome varchar (10)) como início
fim
crie o procedimento [dbo]. [sp_teste_loop] como iniciar
fim
fonte
Concordo com a postagem anterior de que as operações baseadas em conjunto normalmente terão um desempenho melhor, mas se você precisar percorrer as linhas, aqui está a abordagem que eu adotaria:
Selecione o próximo registro não utilizado da tabela e repita o processo
fonte
Etapa 1: A instrução select abaixo cria uma tabela temporária com número de linha exclusivo para cada registro.
Etapa 2: declarar variáveis necessárias
Etapa 3: obter a contagem total de linhas da tabela temporária
Etapa 4: criar uma tabela temporária de loop com base no número de linha exclusivo criado em temp
fonte
Essa abordagem requer apenas uma variável e não exclui nenhuma linha dos @databases. Sei que há muitas respostas aqui, mas não vejo uma que use MIN para obter seu próximo ID como este.
fonte
Aqui está minha solução, que utiliza um loop infinito, a
BREAK
instrução e a@@ROWCOUNT
função. Não são necessários cursores ou tabelas temporárias, e eu só preciso escrever uma consulta para obter a próxima linha da@databases
tabela:fonte
Este é o código que estou usando 2008 R2. Este código que estou usando é para criar índices nos campos-chave (SSNO e EMPR_NO) em todos os contos
fonte
seria melhor:
Evite usar SELECT se você não estiver fazendo referência a tabelas, apenas atribuindo valores.
fonte