SQL puis-je avoir une contrainte "conditionnellement unique" sur une table?
J'ai eu ce arrivé une couple de fois dans ma carrière, et aucun de mes pairs locaux semble être en mesure de répondre. Dire que j'ai une table qui dispose d'un champ "Description", qui est une clé candidate, sauf que parfois, un utilisateur va s'arrêter à mi-chemin à travers le processus. Donc, pour peut-être 25% de la enregistre cette valeur est nulle, mais pour tous ceux qui ne sont pas NULL, il doit être unique.
Un autre exemple pourrait être un tableau qui doit gérer plusieurs "versions" d'un enregistrement, et une valeur de bit indique qui est le plus "active". Ainsi, le "candidat de la clé" est toujours peuplé, mais il peut y avoir trois versions sont identiques (à 0 dans le bit actif) et un seul qui est actif (1 dans le bit actif).
J'ai d'autres méthodes pour résoudre ces problèmes (dans le premier cas, de faire respecter le code de la règle, que ce soit dans la procédure stockée ou la couche de gestion, et dans le second, remplir un tableau d'archives avec un seuil de déclenchement et de l'UNION les tables quand j'ai besoin d'une histoire). Je ne veux pas de solutions de rechange (sauf si il y a manifestement meilleures solutions), je me demandais simplement si toute la saveur de SQL express "conditionnel de l'unicité" de cette façon. Je suis à l'aide de MS SQL, donc si il y a un moyen de le faire que, de la grande. Je suis la plupart du temps seulement sur le plan académique intéressé au problème.
source d'informationauteur Michael Blackburn
Vous devez vous connecter pour publier un commentaire.
Si vous utilisez SQL Server 2008, un filtre d'Index aurait peut-être votre solution:
http://msdn.microsoft.com/en-us/library/ms188783.aspx
C'est comment j'ai appliquer un Index Unique avec plusieurs valeurs NULL
Dans le cas de descriptions qui ne sont pas encore terminé, je n'aurais pas ceux dans la même table que la version finale de descriptions. La table finale aurait alors un index unique ou de clé primaire dans la description.
Dans le cas de l'actif/inactif, je pourrais avoir des tables séparées comme vous l'avez fait avec une "archive" ou "l'histoire" de la table, mais d'une autre façon possible de le faire dans MS SQL Server au moins à travers l'utilisation d'une vue indexée:
Vous pouvez utiliser cette même méthode pour les NULS/Apprécié les descriptions.
Oracle n'. Entièrement clé null n'est pas indexé par un Barbre d'index dans Oracle, Oracle utilise Barbre d'index pour appliquer des contraintes uniques.
En supposant que l'on souhaite à la version ID_COLUMN basé sur la ACTIVE_FLAG être mis à 1:
Merci pour les commentaires, la version initiale de cette réponse était erronée.
Voici un truc à l'aide d'une colonne calculée qui permet effectivement à un nullable contrainte unique dans SQL Server:
Il utilise essentiellement le
id
lorsque lename
est null. Le+ '_'
est d'éviter les cas où le nom peut être numérique, comme1
qui pourraient entrer en collision avec laid
.Je ne suis pas tout à fait conscients de votre utilisation ou de vos tables, mais vous pouvez essayer d'utiliser une relation. Répartir ce "parfois" colonne unique dans une nouvelle table, create UNIQUE index sur cette colonne dans la nouvelle table et FK retour à la table d'origine en utilisant les tables d'origine PK. Seulement une ligne dans cette nouvelle table quand le "uniques" données est supposé exister.
Tableaux ANCIENS:
De NOUVELLES tables: