J'ai une base de données qui n'est pas en production, donc la table principale étant CustodyDetails, cette table a une ID int IDENTITY(1,1) PRIMARY KEY
colonne et je cherche un moyen d'ajouter un autre identifiant unique qui n'est référencé dans aucune autre table, je pense qu'en prenant cela dans compte le contenu de la colonne ne serait pas exactement une clé d'identité.
Cette nouvelle colonne d'identité contient cependant quelques détails spécifiques, et voici où commence mon problème. Le format est le suivant: XX/YY
où XX est une valeur auto-incrémentable qui se réinitialise / redémarre chaque nouvelle année et YY est les 2 derniers chiffres de l'année en cours SELECT RIGHT(YEAR(GETDATE()), 2)
.
Ainsi, par exemple, supposons qu'un enregistrement est ajouté un jour à partir du 28/12/2015 se terminant le 03/01/2016 , la colonne ressemblerait à:
ID ID2 DATE_ADDED
1 1/15 2015-12-28
2 2/15 2015-12-29
3 3/15 2015-12-30
4 4/15 2015-12-31
5 1/16 2016-01-01
6 2/16 2016-01-02
7 3/16 2016-01-03
J'ai pensé à utiliser l'interface pour analyser l'ID composite (ID2 dans l'exemple), obtenir les 2 derniers chiffres et comparer avec les 2 derniers chiffres de l'année en cours, puis décider de commencer ou non une nouvelle corrélation. Bien sûr, ce serait formidable de pouvoir tout faire du côté de la base de données.
EDIT 1: btw, j'ai également vu des gens utiliser des tables distinctes juste pour stocker des clés d'identité parallèles, donc une clé d'identité de table devient une deuxième clé secondaire de table, cela semble un peu douteux mais c'est peut-être le cas si une telle implémentation est en place?
EDIT 2: Cet ID supplémentaire est une référence de document héritée qui étiquette chaque fichier / enregistrement. Je suppose que l'on pourrait le considérer comme un alias spécial pour l'ID principal.
Le nombre d'enregistrements que cette base de données gère chaque année n'a pas été parmi les 100 au cours des 20 dernières années et il est hautement (vraiment, extrêmement fortement) improbable que cela le fasse, bien sûr, s'il dépasse 99, le champ pourra continuez avec le chiffre supplémentaire et le frontend / procédure pourra dépasser 99, donc ce n'est pas comme si cela changeait les choses.
Bien sûr, certains de ces détails que je n'ai pas mentionnés au début, car ils ne feraient que restreindre les possibilités de solution pour répondre à mes besoins spécifiques, ont essayé de garder la gamme de problèmes plus large.
ID
= 5, 6 et 7, le DATE_ADDED devrait être2016-01-01
et ainsi de suite?Réponses:
Vous pouvez utiliser une table de clés pour stocker la partie incrémentielle de votre deuxième colonne ID. Cette solution ne repose sur aucun code côté client et prend automatiquement en compte plusieurs années; lorsque le
@DateAdded
paramètre passe dans une année précédemment inutilisée, il commencera automatiquement à utiliser un nouvel ensemble de valeurs pour laID2
colonne, basé sur cette année. Si le proc est par conséquent utilisé pour insérer des lignes des années précédentes, ces lignes seront insérées avec des valeurs "correctes" pour l'incrément. LeGetNextID()
proc est conçu pour gérer les blocages possibles avec élégance, ne transmettant une erreur à l'appelant que si 5 blocages séquentiels se produisent lors de la tentative de mise à jour de latblIDs
table.Créez une table pour stocker une ligne par an contenant la valeur d'ID actuellement utilisée, ainsi qu'une procédure stockée pour renvoyer la nouvelle valeur à utiliser:
Votre table, avec un proc pour y insérer des lignes:
Insérez quelques exemples de données:
Afficher les deux tableaux:
Résultats:
La table des clés et le proc stocké proviennent de cette question.
la source
(IDName, LastID)
ligne, cela entraînerait-il un blocage ou l'une des transactions violant le PK? Dans ce dernier cas, il serait peut-être judicieux de donner à cette transaction une autre chance (afin qu'elle obtienne finalement l'ID de 2).@NewID
explicitement la valeur null au début de la boucle: si la transaction qui tente d'insérer une ligne devient une victime de blocage, elle n'essaiera pas d'insérer une ligne à la prochaine itération, car@NewID
aura déjà a été défini sur 1 (ce qui n'est pas NULL, et donc la branche INSERT sera omise).tblIDs
table puisque cette table est mise à jour par une seule opération atomique; la mise à jour "décalée".@NewID = NULL
en début de boucle.