3

Je connais les champs IDENTITY mais j'ai l'impression que je ne pourrais pas en utiliser un pour résoudre mon problème.Comment dois-je procéder pour implémenter un champ "autonumber" dans SQL Server 2005?

Disons que j'ai plusieurs clients. Chaque client a plusieurs commandes. Chaque client doit avoir ses commandes numérotées de manière séquentielle, spécifique à lui.

structure de la table Exemple:

Orders: 
OrderID | ClientID | ClientOrderID | etc... 

Quelques exemples de lignes pour cette table serait:

OrderID | ClientID | ClientOrderID | etc... 
1 | 1 | 1 | ... 
2 | 1 | 2 | ... 
3 | 2 | 1 | ... 
4 | 3 | 1 | ... 
5 | 1 | 3 | ... 
6 | 2 | 2 | ... 

Je connais le chemin naïve serait de prendre le MAX ClientOrderID pour tout client et utiliser cette valeur pour INSERT mais cela serait soumis à des problèmes de concurrence. J'envisageais d'utiliser une transaction, mais je ne suis pas sûr de la portée d'isolement la plus large qui puisse être utilisée pour cela. J'utiliserai LINQ to SQL mais j'ai le sentiment que ce n'est pas pertinent.

+0

Alors, je dois demander ... POURQUOI voulez-vous faire cela? –

+0

Cela ressemble à quelqu'un qui n'est pas habitué au stockage de données vous demande de le faire. Créer des dates est une façon plus naturelle de le faire. –

+0

Je pourrais probablement juste attribuer un horodatage à chaque commande, puis faire un COUNT pour obtenir le numéro de commande pour le client. Cela ne devrait pas être un problème de performance car la table ne sera pas beaucoup plus grande que 1000 enregistrements. – llamaoo7

Répondre

2

Quelqu'un me corriger si je me trompe, mais aussi longtemps que votre appel MAX() est dans la même étape que votre insert, vous ne serez pas avoir un problème avec la concurrence.

Ainsi, vous pourriez pas faire

select @newOrderID=max(ClientOrderID) + 1 
from orders 
where [email protected]; 

insert into (ClientID, ClientOrderID, ...) 
values(@myClientID, @newOrderID, ...); 

Mais vous pouvez faire

insert into (ClientID, ClientOrderID, ...) 
select @myClientID, max(ClientOrderID) + 1, ... 
from orders 
where [email protected]; 

Je suppose OrderID est une colonne d'identité.

Encore une fois, si je me trompe sur ce point, s'il vous plaît laissez-moi savoir. De préférence avec une URL

1

Vous pouvez utiliser un modèle référentiel pour gérer vos commandes et laissez contrôler le nombre de clients chaque numéro de commande spécifiques. Si vous implémentez le OrderRepository correctement, il pourrait contrôler la concurrence et numéroter l'ordre avant de l'enregistrer dans la base de données (laissez le dépôt et non le db définir le numéro).

pattern Repository: http://martinfowler.com/eaaCatalog/repository.html

1

Une possibilité (bien que je n'aime pas le faire) est d'avoir une table de recherche qui vous dira le plus grand numéro de commande donné pour chaque fournisseur. À l'intérieur d'une transaction, vous récupérerez la plus récente de VendorOrderNumber, enregistrez votre nouvelle commande, incrémentez la valeur dans VendorOrderNumber, validez la transaction.

1

Ceci est une étrange façon de stocker des données, mais en supposant que vous en avez besoin, il n'y a rien dans INTÉGRÉE que vous pouvez utiliser.

Votre suggestion de Max (ClientOrderID) est simple et assez facile à mettre en œuvre (suivre les conseils de John MacIntyre). Il fonctionnera probablement bien sur des tables avec quelques milliers de commandes. À mesure que le tableau se développe, cette approche va bien sûr ralentir.

Nick suggestion de DeVore d'une table de recherche est un peu messier à mettre en œuvre, mais ne sera pas substantiellement affectée par la croissance des données.

Selon l'endroit où/quand vous avez besoin en fait le ClientOrderID, vous pouvez calculer l'id en cas de besoin comme ceci:

SELECT *, 
ROW_NUMBER() OVER(ORDER BY OrderID) AS ClientOrderID 
FROM Orders 
WHERE ClientID = 1 

Cela suppose que les ClientOrderIDs sont dans la même séquence que le OrderID. Sans réellement persister l'ID, il est difficile d'utiliser comme une clé pour toute autre chose. Cette approche ne devrait pas être affectée par la croissance des données.

Questions connexes