Estou tentando conseguir algo parecido com um for-each, onde gostaria de pegar os IDs de uma instrução select retornada e usar cada um deles.
DECLARE @i int
DECLARE @PractitionerId int
DECLARE @numrows int
DECLARE @Practitioner TABLE (
idx smallint Primary Key IDENTITY(1,1)
, PractitionerId int
)
INSERT @Practitioner
SELECT distinct PractitionerId FROM Practitioner
SET @i = 1
SET @numrows = (SELECT COUNT(*) FROM Practitioner)
IF @numrows > 0
WHILE (@i <= (SELECT MAX(idx) FROM Practitioner))
BEGIN
SET @PractitionerId = (SELECT PractitionerId FROM @Practitioner WHERE idx = @i)
--Do something with Id here
PRINT @PractitionerId
SET @i = @i + 1
END
No momento, tenho algo parecido com o acima, mas estou recebendo o erro:
Nome de coluna inválido 'idx'.
Alguém poderia
sql-server
tsql
Pomster
fonte
fonte
idx
está em@Practitioner
nãoPractitioner
. Na maioria das vezes, existem alternativas superiores baseadas em conjuntos a uma abordagem para cada um, se você mostrar o que faz com o valor da linha, talvez uma alternativa possa ser sugerida.--Do something with Id here
é, é provável que possamos mostrar como resolver esse problema sem loops ou cursores. Na maioria dos casos, você deseja usar uma solução baseada em conjunto, pois é assim que o SQL Server é otimizado para funcionar. Dar laços e tratar uma linha de cada vez certamente tem seu lugar, mas suspeito que não seja isso.Respostas:
Você parece querer usar um
CURSOR
. Embora na maioria das vezes seja melhor usar uma solução baseada em conjunto, há momentos em que aCURSOR
é a melhor solução. Sem saber mais sobre o seu problema real, não podemos ajudá-lo mais do que isso:fonte
Suponha que a coluna PractitionerId seja única, então você pode usar o seguinte loop
fonte
Sua contagem de seleção e máximo de seleção devem ser da sua variável de tabela em vez da tabela real
fonte
Isso geralmente (quase sempre) tem um desempenho melhor que um cursor e é mais simples:
fonte
Eu diria que tudo provavelmente funciona, exceto que a coluna
idx
realmente não existe na tabela que você selecionou. Talvez você pretenda selecionar entre@Practitioner
:porque isso é definido no código acima assim:
fonte
A seguinte linha está incorreta na sua versão:
(Faltando o @)
Pode ser uma ideia alterar sua convenção de nomenclatura para que as tabelas sejam mais diferentes.
fonte
Embora os cursores geralmente sejam considerados horríveis, acredito que este é o caso do cursor FAST_FORWARD - a coisa mais próxima que você pode obter do FOREACH no TSQL.
fonte
Eu vim com uma maneira muito eficaz, (eu acho) legível de fazer isso.
Aqui está o código. Desculpe, está usando meus nomes de variáveis em vez dos nomes da pergunta.
fonte
Aqui está uma das melhores soluções.
Podemos acessar ou podemos fazer qualquer coisa no corpo do loop e podemos acessar o idx definindo-o dentro da definição da tabela.
fonte
Eu fiz um procedimento que executa um
FOREACH
comCURSOR
para qualquer tabela.Exemplo de uso:
O resultado são 2 seleções para cada linha. A sintaxe
UPDATE
e a quebraFOREACH
são escritos nas dicas.Este é o código proc:
fonte