2010-07-07 4 views
1

Je vais avoir du mal à comprendre les éléments suivants OU clause dans T-SQL (SQL Server 2000/2005) requête:Que signifie cette clause SQL WHERE?

update #tempTable 
SET 
    Total_Avg=isnull(TerminationReason,'terminated'), 
    Individual_Subscriptions=null, 
    Business_Subscriptions=null, 
    Other_subscriptions=null, 
    -- snip. 10 more fields set to NULL. 
    PMIE_BI=null, 
    Digital_Editions_BI=null 
where 
(
    AbcTerminationDate<=dbo.fnGetPeriodFinalDate(@periodid) 
    and (AbcTerminationDate!=19000101 or AbcTerminationDate is null) 
    and (Total_Avg is not NULL or PrevTotalAvg is not NULL) 
) 

Plus précisément, la deuxième clause n'a pas de sens pour moi - c'est 2 sous-clauses séparées par l'opérateur ou semblent contradictoires.

Le AbcTerminationDate champ est déclaré comme INT NULL dans une table appelée Membres. Je crois qu'une date de dans le système signifie NULL ou une valeur par défaut ou aucune valeur, c'est-à-dire qu'un membre est et non terminé. La requête semble donc masquer un grand nombre de champs/chiffres si un membre est marqué comme terminé, ce qui correspond à AbcTerminationDate est NULL ou a la valeur par défaut.

Sans en savoir plus, qu'en faites-vous?

Répondre

3

Il semble que ce soit contradictoire. Peut-être qu'ils signifiaient and !(AbcTerminationDate==19000101 or AbcTerminationDate is null) ?

+0

Exactement ce que je pensais. J'espérais que quelqu'un d'autre aurait pris ça aussi .. –

+0

http://en.wikipedia.org/wiki/De_Morgan%27s_laws est ce que je pensais. Mais ils ont réussi à tout rafistoler, mais d'une manière ou d'une autre, cela fonctionnait toujours à cause d'une logique étrange, et échouait seulement dans certains cas. –

1

Si le « ou » arg étaient en dehors du() groupant annulerait:

AbcTerminationDate<=dbo.fnGetPeriodFinalDate(@periodid) 

[modifier] Fondamentalement, il est dit de prendre les résultats sont vrais de cette 1ère clause, et effectuer une filtre supplémentaire pour s'assurer que ce n'est pas 19000101 ou il est nul, sont probablement des valeurs exceptionnelles pour la fonction fnGetPeriodFinalDate pour évaluer correctement.

+0

Merci .. a du sens. Je suis surtout intéressé par la 2ème clause et ce que cela signifie, mais les résultats de celle-ci pourraient annuler la première clause, donc la première clause doit être considérée aussi bien pour extraire le sens ... –

1

Quoi que 19000101 soit "supposé" signifier, ce n'est pas la même chose que NULL aux yeux de la base de données. NULL est NULL. Si vous essayez d'évaluer n'importe quelle autre valeur à NULL, cela peut devenir problématique, car NULL signifie "inconnu". Par exemple, est-ce que 1 = NULL? Peut-être que oui, peut-être que non. En fait, vous ne pouvez même pas dire que NULL = NULL, parce que chaque valeur NULL est inconnue, donc peut-être ou ne pas être égal à l'autre. Il est plus sûr de vérifier explicitement les conditions NULL.

EDIT: Comme je le souligne dans mon commentaire, si NULLs doivent être inclus, la première partie de la requête exclut cela. Voici comment il devrait être écrit si NULLs devrait être inclus:

(
    (
     (
      AbcTerminationDate <= dbo.fnGetPeriodFinalDate(@periodid) AND 
      AbcTerminationDate != 19000101 
     ) OR 
     AbcTerminationDate is NULL 
    ) AND 
    (Total_Avg is not NULL or PrevTotalAvg is not NULL) 
) 
+0

D'accord, et le code ci-dessus semble être une pratique assez courante. Tout simplement parce que AbcTerminationDate n'est pas égal à "19000101" ne signifie pas qu'il est égal à NULL ... comme vous l'avez dit, vous devez tester spécifiquement pour cela. – Faisal

+0

Je ne conteste pas ce que vous dites, et je comprends ce que NULL signifie d'un point de vue technique. Mais ce n'est pas ma question. Dans le système, une valeur de date de 19000101 est "sementically" équivalente à une valeur NULL.Je suis plus intéressé par la valeur sémantique de la requête - qu'essaient-ils de réaliser? –

+0

Si ce n'est pas la date de référence, incluez-la. Si c'est NULL, alors incluez-le. Encore une fois, indépendamment de la sémantique, la requête doit toujours être techniquement correcte si vous voulez les bons résultats. C'est ce que cette ligne de code essaie de faire - assurez-vous que les résultats corrects sont retournés si la date est NULL. Il ne le fait pas bien, car si c'est NULL alors la première partie de la requête échouera probablement. –