Eu tenho um procedimento armazenado que altera os dados do usuário de uma certa maneira. Eu passo-o user_id e faz é coisa. Eu quero executar uma consulta em uma tabela e, em seguida, para cada user_id eu acho executar o procedimento armazenado uma vez nesse user_id
Como eu escreveria uma consulta para isso?
sql
sql-server
stored-procedures
MetaGuru
fonte
fonte
Respostas:
use um cursor
ADENDO: [Exemplo de cursor do MS SQL]
no MS SQL, aqui está um artigo de exemplo
observe que os cursores são mais lentos que as operações baseadas em conjuntos, mas mais rápidos que os loops manuais manuais; mais detalhes nesta questão SO
ADENDO 2: se você estiver processando mais do que apenas alguns registros, puxe-os para uma tabela temporária primeiro e passe o cursor sobre a tabela temporária; isso impedirá que o SQL passe para bloqueios de tabela e acelere a operação
ADENDO 3: e, é claro, se você puder incorporar o que o procedimento armazenado está fazendo a cada ID de usuário e executar tudo como uma única instrução de atualização SQL, isso seria ideal
fonte
tente alterar seu método se precisar fazer um loop!
dentro do procedimento armazenado pai, crie uma tabela #temp que contém os dados que você precisa processar. Chame o procedimento armazenado filho, a tabela #temp estará visível e você poderá processá-lo, trabalhando com todo o conjunto de dados e sem um cursor ou loop.
isso realmente depende do que esse procedimento armazenado filho está fazendo. Se você está atualizando, pode "atualizar de" ingressando na tabela #temp e fazer todo o trabalho em uma instrução sem um loop. O mesmo pode ser feito para INSERT e DELETEs. Se você precisar fazer várias atualizações com IFs, poderá convertê-las em várias
UPDATE FROM
com a tabela #temp e usar instruções CASE ou condições WHERE.Ao trabalhar em um banco de dados, tente perder a mentalidade de fazer loop, é uma perda real de desempenho, causará bloqueio / bloqueio e atrasará o processamento. Se você fizer um loop em qualquer lugar, seu sistema não será muito bem dimensionado e será muito difícil acelerar quando os usuários começarem a reclamar de atualizações lentas.
Poste o conteúdo deste procedimento que você deseja chamar em um loop, e aposto 9 em 10 vezes, você pode escrever para trabalhar em um conjunto de linhas.
fonte
Algo como essas substituições será necessário para suas tabelas e nomes de campos.
fonte
Você pode fazer isso com uma consulta dinâmica.
fonte
Isso não pode ser feito com uma função definida pelo usuário para replicar o que o procedimento armazenado está fazendo?
onde udfMyFunction é uma função que você cria, que recebe o ID do usuário e faz o que for necessário.
Consulte http://www.sqlteam.com/article/user-defined-functions para obter um pouco mais de experiência
Concordo que os cursores realmente devem ser evitados sempre que possível. E geralmente é possível!
(é claro, minha resposta pressupõe que você só está interessado em obter a saída do SP e que não está alterando os dados reais. Acho que "altera os dados do usuário de uma certa maneira" um pouco ambíguo da pergunta original, então pensei em oferecer isso como uma solução possível. Depende totalmente do que você está fazendo!)
fonte
Use uma variável de tabela ou uma tabela temporária.
Como mencionado anteriormente, um cursor é o último recurso. Principalmente porque usa muitos recursos, bloqueia problemas e pode ser um sinal de que você simplesmente não está entendendo como usar o SQL corretamente.
Crie uma variável de tabela como esta (se você estiver trabalhando com muitos dados ou tiver pouca memória, use uma tabela temporária ):
o
id
é importante.Substitua
parent
echild
por alguns bons dados, por exemplo, identificadores relevantes ou todo o conjunto de dados a ser operado.Inserir dados na tabela, por exemplo:
Declare algumas variáveis:
E, finalmente, crie um loop while sobre os dados da tabela:
A primeira seleção busca dados da tabela temporária. A segunda seleção atualiza o @id.
MIN
retorna nulo se nenhuma linha foi selecionada.Uma abordagem alternativa é fazer um loop enquanto a tabela possui linhas
SELECT TOP 1
e remover a linha selecionada da tabela temporária:fonte
Eu gosto da maneira de consulta dinâmica de Dave Rincon, pois não usa cursores e é pequeno e fácil. Obrigado Dave por compartilhar.
Mas, para as minhas necessidades no SQL do Azure e com um "distinto" na consulta, tive que modificar o código da seguinte maneira:
Espero que isso ajude alguém...
fonte