Pergunta

Eu tenho um script SQL que insere dados (por meio de instruções INSERT atualmente numeradas na casa dos milhares). Uma das colunas contém um identificador exclusivo (embora não seja um tipo IDENTITY, apenas um simples e velho int) que é realmente exclusivo em algumas tabelas diferentes.

Gostaria de adicionar uma função escalar ao meu script que obtenha o próximo ID disponível (ou seja,último ID usado + 1), mas não tenho certeza se isso é possível porque não parece haver uma maneira de usar uma variável global ou estática de dentro de uma UDF, não posso usar uma tabela temporária e posso ' atualizar uma tabela permanente de dentro de uma função.

Atualmente meu script está assim:

   declare @v_baseID int 
   exec dbo.getNextID @v_baseID out  --sproc to get the next available id
   --Lots of these - where n is a hardcoded value
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', @v_baseID + n ) 
   exec dbo.UpdateNextID @v_baseID + lastUsedn  --sproc to update the last used id

Mas eu gostaria que ficasse assim:

   --Lots of these
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', getNextID() ) 

Codificar o deslocamento é um pé no saco e está sujeito a erros.Empacotá-lo em uma função escalar simples é muito atraente, mas estou começando a achar que não pode ser feito dessa maneira, pois não parece haver uma maneira de manter o contador de deslocamento entre as chamadas.Está certo ou há algo que estou perdendo.

Estamos usando o SQL Server 2005 no momento.

edições para esclarecimento:

Dois usuários acertando isso não acontecerá.Este é um script de atualização que será executado apenas uma vez e nunca simultaneamente.

O sproc real não é prefixado com sp_, corrigiu o código de exemplo.

No uso normal, usamos uma tabela de id e um sproc para obter IDs conforme necessário. Eu estava apenas procurando uma maneira mais limpa de fazer isso neste script, que basicamente despeja um monte de dados no banco de dados.

Foi útil?

Solução

Estou começando a achar que isso não pode ser feito dessa maneira, pois não parece haver uma maneira de manter o contador de deslocamento entre as chamadas.Está certo ou há algo que estou perdendo.

Você não está perdendo nada;O SQL Server não oferece suporte a variáveis ​​globais e não oferece suporte à modificação de dados em UDFs.E mesmo se você quisesse fazer algo tão desajeitado como usar CONTEXT_INFO (veja http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx), você não pode definir isso de dentro de uma UDF.

Existe uma maneira de contornar a "codificação" do deslocamento, tornando-a uma variável e fazendo um loop na iteração dela, fazendo as inserções dentro desse loop?

Outras dicas

Se você tiver 2 usuários acessando ao mesmo tempo, eles obterão o mesmo ID.Por que você não usou uma tabela de id com uma identidade, inseriu-a e usou-a como o id exclusivo (que é garantido), isso também terá um desempenho muito mais rápido

sp_getNextID

nunca prefixe procs com sp_, isso tem implicações no desempenho porque o otimizador primeiro verifica o banco de dados mestre para ver se esse proc existe lá e depois o banco de dados local, também se a MS decidir criar um sp_getNextID em um service pack, o seu nunca será executado

Provavelmente daria mais trabalho do que vale a pena, mas você pode usar variáveis ​​estáticas C#/VB em uma UDF SQL CLR, então acho que você seria capaz de fazer o que deseja simplesmente incrementando essa variável toda vez que a UDF for chamado.A variável estática seria perdida sempre que o appdomain fosse descarregado, é claro.Então se você precisar de continuidade do seu ID de um dia para o outro, você precisaria de uma forma, no primeiro acesso do NextId, de pesquisar todas as tabelas que usam esse ID, para encontrar o valor mais alto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top