Question

J'ai un script SQL qui insère des données (via des instructions INSERT qui se comptent actuellement par milliers). L'une des colonnes contient un identifiant unique (mais pas un type IDENTITY, juste un simple int) qui est en fait unique sur quelques tables différentes.

J'aimerais ajouter une fonction scalaire à mon script qui obtient le prochain identifiant disponible (c'est-à-direID utilisé pour la dernière fois + 1) mais je ne suis pas sûr que cela soit possible car il ne semble pas y avoir de moyen d'utiliser une variable globale ou statique à partir d'une UDF, je ne peux pas utiliser de table temporaire et je peux ' t mettre à jour une table permanente à partir d’une fonction.

Actuellement, mon script ressemble à ceci :

   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

Mais j'aimerais que ça ressemble à ça :

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

Le codage en dur du décalage est pénible et sujet aux erreurs.Le regrouper dans une simple fonction scalaire est très attrayant, mais je commence à penser que cela ne peut pas être fait de cette façon car il ne semble pas y avoir de moyen de maintenir le compteur de décalage entre les appels.Est-ce vrai, ou y a-t-il quelque chose qui me manque.

Nous utilisons SQL Server 2005 pour le moment.

modifications pour clarification :

Deux utilisateurs ne le frapperont pas.Il s'agit d'un script de mise à niveau qui ne sera exécuté qu'une seule fois et jamais simultanément.

Le sproc réel n'est pas préfixé par sp_, correction de l'exemple de code.

Dans une utilisation normale, nous utilisons une table d'identification et un sproc pour obtenir les identifiants selon les besoins. Je cherchais simplement un moyen plus propre de le faire dans ce script, qui consiste essentiellement à vider un tas de données dans la base de données.

Était-ce utile?

La solution

Je commence à penser que cela ne peut pas être fait de cette façon car il ne semble pas y avoir de moyen de maintenir le compteur de décalage entre les appels.Est-ce vrai, ou y a-t-il quelque chose qui me manque.

Vous ne manquez de rien ;SQL Server ne prend pas en charge les variables globales et ne prend pas en charge la modification des données dans les UDF.Et même si vous vouliez faire quelque chose d'aussi compliqué que d'utiliser CONTEXT_INFO (voir http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx), vous ne pouvez de toute façon pas définir cela depuis une UDF.

Existe-t-il un moyen de contourner le "codage en dur" du décalage en en faisant une variable et en bouclant son itération, en effectuant les insertions dans cette boucle ?

Autres conseils

Si 2 utilisateurs le cliquent en même temps, ils obtiendront le même identifiant.Pourquoi n'avez-vous pas utilisé une table d'identification avec une identité à la place, insérez-la et utilisez-la comme identifiant unique (qui est garanti), cela fonctionnera également beaucoup plus rapidement

sp_getNextID

ne préfixez jamais procs avec sp_, cela a des implications en termes de performances car l'optimiseur vérifie d'abord la base de données principale pour voir si cette procédure existe là-bas, puis la base de données locale, également si MS décide de créer un sp_getNextID dans un service pack, le vôtre ne sera jamais exécuté

Ce serait probablement plus de travail que cela n'en vaut la peine, mais vous pouvez utiliser des variables statiques C#/VB dans un UDF SQL CLR, donc je pense que vous seriez en mesure de faire ce que vous voulez en incrémentant simplement cette variable à chaque fois que l'UDF est appelé.La variable statique serait perdue à chaque fois que le domaine d'application serait déchargé, bien sûr.Ainsi, si vous avez besoin d'une continuité de votre identifiant d'un jour à l'autre, vous aurez besoin d'un moyen, lors du premier accès à NextId, d'interroger toutes les tables qui utilisent cet identifiant, pour trouver la valeur la plus élevée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top