La réponse de @ ypercube gère cela partiellement en tant que changement de métadonnées uniquement.
L'ajout de la contrainte NOCHECK
signifie qu'aucune ligne ne devra être lue pour la vérifier, et si vous partez d'une position où la colonne ne contient pas de NULL
valeurs (et si vous savez qu'aucune ne sera ajoutée entre la vérification et l'ajout de la contrainte), alors, comme la contrainte empêche la NULL
création de valeurs à partir de futures INSERT
ou d' UPDATE
opérations, cela fonctionnera.
L'ajout de la contrainte peut cependant avoir un impact sur les transactions simultanées. Le ALTER TABLE
devra d'abord acquérir une Sch-M
serrure. Pendant qu'il attend cela, tous les autres accès à la table seront bloqués comme décrit ici .
Une fois le Sch-M
verrou acquis, l'opération devrait cependant être assez rapide.
Un problème avec cela est que même si vous savez que la colonne n'a pas de NULL
s, la contrainte n'est pas approuvée par l'optimiseur de requête, ce qui signifie que les plans peuvent être sous-optimaux.
CREATE TABLE T (X INT NULL)
INSERT INTO T
SELECT ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values
ALTER TABLE T WITH NOCHECK
ADD CONSTRAINT X_NOT_NULL
CHECK (X IS NOT NULL) ;
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Comparez cela avec le plus simple
ALTER TABLE T ALTER COLUMN X INT NOT NULL
SELECT *
FROM T
WHERE X NOT IN (SELECT X FROM T)
Un problème possible que vous pourriez rencontrer avec la modification de la définition de colonne de cette manière est qu'il doit non seulement lire toutes les lignes pour vérifier qu'elles remplissent la condition, mais peut également finir par effectuer des mises à jour journalisées des lignes .
Une solution intermédiaire pourrait être d'ajouter la contrainte de vérification WITH CHECK
. Cela sera plus lent que WITH NOCHECK
nécessaire pour lire toutes les lignes, mais cela permet à l'optimiseur de requête de donner le plan le plus simple dans la requête ci-dessus et il devrait éviter le problème de mises à jour enregistrées possibles.