web-dev-qa-db-fra.com

Comment rendre une colonne de vue NON NULLE

J'essaie de créer une vue dans laquelle je souhaite qu'une colonne soit uniquement vraie ou fausse. Cependant, il semble que, quoi que je fasse, SQL Server (2008) pense que ma colonne de bits peut en quelque sorte être nulle.

J'ai un tableau appelé "Produit" avec la colonne "Statut" qui est INT, NULL. Dans une vue, je veux renvoyer une ligne pour chaque ligne dans Product, avec une colonne BIT définie sur true si la colonne Product.Status est égale à 3, sinon le champ de bit doit être faux.

Exemple SQL

SELECT CAST( CASE ISNULL(Status, 0)  
               WHEN 3 THEN 1  
               ELSE 0  
             END AS bit) AS HasStatus  
FROM dbo.Product  

Si j'enregistre cette requête en tant que vue et regarde les colonnes dans l'Explorateur d'objets, la colonne HasStatus est définie sur BIT, NULL. Mais cela ne devrait jamais être NULL. Y a-t-il une astuce SQL magique que je peux utiliser pour forcer cette colonne à être NOT NULL.

Notez que si je supprime la CAST() autour de la CASE, la colonne est correctement définie comme NOT NULL, Mais le type de la colonne est défini sur INT , ce qui n'est pas ce que je veux. Je veux que ce soit BIT. :-)

74
René

Vous pouvez réaliser ce que vous voulez en réorganisant un peu votre requête. L'astuce est que le ISNULL doit être à l'extérieur avant que SQL Server comprenne que la valeur résultante ne peut jamais être NULL.

SELECT ISNULL(CAST(
    CASE Status
        WHEN 3 THEN 1  
        ELSE 0  
    END AS bit), 0) AS HasStatus  
FROM dbo.Product  

L'une des raisons pour lesquelles je trouve cela utile est lorsque vous utilisez un ORM et que vous ne voulez pas que la valeur résultante soit mappée sur un type nullable. Cela peut faciliter les choses si votre application considère que la valeur n'est jamais nulle. Ensuite, vous n'avez pas à écrire de code pour gérer les exceptions nulles, etc.

138
RedFilter

Pour info, pour les personnes rencontrant ce message, l'ajout de ISNULL () à l'extérieur de la distribution/conversion peut perturber l'optimiseur sur votre vue.

Nous avions 2 tables utilisant la même valeur comme clé d'index mais avec des types de précision numérique différente (mauvaise, je sais) et notre point de vue se joignait à elles pour produire le résultat final. Mais notre code middleware cherchait un type de données spécifique, et la vue avait un CONVERT () autour de la colonne renvoyée

J'ai remarqué, comme l'OP l'a fait, que les descripteurs de colonne du résultat de la vue le définissaient comme nullable et je pensais que c'était une clé primaire/étrangère sur 2 tables; pourquoi voudrions-nous que le résultat soit défini comme nul?

J'ai trouvé ce message, jeté ISNULL () autour de la colonne et le tour est joué - plus nul.

Le problème était que les performances de la vue descendaient directement dans les toilettes lorsqu'une requête filtrée sur cette colonne.

Pour une raison quelconque, un CONVERT () explicite dans la colonne de résultat de la vue n'a pas vissé l'optimiseur (il allait devoir le faire de toute façon en raison des différentes précisions), mais l'ajout d'un wrapper ISNULL () redondant l'a fait, dans un grand façon.

3
user1664043