Une fonction SQL Server pour générer des numéros séquentiels

Je voudrais avoir une fonction SQL Server dbo.GetNextNumber() , qui produirait des nombres séquentiels pour chaque appel. Pour autant que je sache, cela est impossible avec une fonction T-SQL native car SQL Server insiste sur le fait que les fonctions doivent être déterministes. Mais, si vous pouviez me montrer une fonction T-SQL native, cela ferait vraiment ma journée.

Je pensais que cela pourrait être possible d'écrire en utilisant une fonction CLR. Comme les fonctions CLR sont statiques, les numéros de séquence doivent être stockés dans le context d'appel de l'opération set, car le stocker comme une variable statique entraînerait plusieurs connections utilisant la même séquence, résultant en des nombres pas si séquentiels. Je ne connais pas assez le CLR embarqué pour voir si le context d'appel de l'opération set (select, update, delete, insert) est accessible depuis le côté CLR.

À la fin de la journée, la requête suivante

 select dbo.GetNextNumber() from sysobjects 

doit renvoyer le résultat

 1 2 3 4 5 

C'est OK si un autre appel de fonction pour réinitialiser le context est nécessaire comme

 exec dbo.ResetSequenceNumbers() 

Pour éviter certains malentendus et réduire les chances de perdre votre time à répondre à une mauvaise question, veuillez noter que je ne cherche pas de fonction de génération d'ID pour une table et je suis conscient de certains hacks (quoique utilisant un proc pas une fonction) tables temporaires avec des colonnes d'identité. La fonction ROW_NUMBER() est proche mais elle ne coupe pas non plus.

Merci beaucoup pour vos réponses

Kemal

Post-scriptum Il est étonnant que SQL Server a une fonction embeddede pour cela. Une fonction (à condition qu'elle ne puisse pas être utilisée dans les clauses join et where) est vraiment facile à faire et extrêmement utile, mais pour une raison quelconque, elle n'est pas incluse.

Comme vous avez implémenté la séquence CLR en fonction de mon article relatif au calcul des totaux cumulés, vous pouvez get la même chose en utilisant la fonction ROW_NUBER() .

La fonction ROW_NUMBER() nécessite ORDER BY dans la clause OVER , cependant il existe une solution de contournement pour éviter le sorting en raison de ORDER BY . Vous ne pouvez pas mettre une expression dans l'ordre, mais vous pouvez y placer SELECT aConstant . Vous pouvez donc facilement générer des nombres en utilisant l'instruction ci-dessous.

 SELECT    ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNumber,    * FROM aTable 

Dans la prochaine version de SQL Server, vous pouvez utiliser une SEQUENCE pour cela. Dans les versions antérieures, il est assez facile de le faire en insérant dans une "table de séquence" séparée (une table avec seulement une colonne IDENTITY), puis en récupérant la valeur avec la fonction SCOPE_IDENTITY (). Vous ne pourrez pas le faire dans une fonction mais vous pouvez utiliser une procédure stockée.

Pouvez-vous donner plus d'informations sur pourquoi ROW_NUMBER() ne le coupe pas? Dans l'exemple spécifique que vous donnez, ROW_NUMBER() (avec la clarification appropriée de OVER(ORDER BY) ) semble certainement correspondre à vos critères.

Mais il y a certainement des cas où ROW_NUMBER() peut ne pas être utile, et dans ces cas, il y a généralement d'autres techniques.

Peut-être que cette fonction générale vous semble utile, mais dans la plupart des cas, je trouve qu'une solution mieux adaptée au problème est une meilleure idée qu'une fonction générale qui finit par causer plus de difficultés – comme une abstraction qui fuit. autour. Vous mentionnez spécifiquement le besoin d'avoir une fonction de réinitialisation. Aucune telle chose n'est nécessaire avec ROW_NUMBER() , étant donné qu'il a le OVER(PARTITION BY ORDER BY) qui vous permet de spécifier le groupement.

SQL Server Denali a une nouvelle structure de séquence pour les développeurs Il est facile de gérer et de maintenir les numéros de séquence dans SQL Server après Denali Vous pouvez find des détails dans les numéros de séquence dans SQL Server

Pour les autres versions que Denali, vous pouvez utiliser des tables de séquences. Voici un exemple de table de séquence dans SQL Server Pour lire le numéro de séquence à partir de la table de séquence, vous devez insert des loggings fictifs à partir de cette table sql à identité automatique activée