Re: Strange Wierdness with SQLServer Bit fields and SQLProvider

Marc Brooks <[email protected]>
Newsgroups gmane.comp.windows.devel.dotnet.clr
Message-ID <[email protected]>
> Admittedly, null may act weird sometime.

NULL acts wierd ALL the time... how else can you talk about something
that is simultaneously equal AND not-equal to itself (see NaN in IEEE
float formats for another edge-case waiting to bite you).

> If you loose null, you loose lots of things that null enables in advanced
> designing.

<singing> Anything NULL can do, a valid-flag can do clearer </singing>

Seriously, NULL is considered anathema in SQL databases by one of the
INVENTORS of SQL.  Chris Date (of Date & Cobb) fame considers NULL in
databases to be "inherently flawed".  The other guy (E.F. Date), who
supports NULL considers the current NULL to be "completely inadequate"
and suggest that you need TWO NULLs to indicate whether something is
"missing but applicable" or "missing but NOT applicable".  The fact
that the two guys that started the whole mess don't agree that it
should be there, and that the one that says it should argues that it's
not right as-is tells me something. [0]

So, you want a special value (NULL) that must be logically interpreted
every where it is used instead of a flag that consistently indicates
the true meaning... I'll have to agree to disagree with that.

> A practical application is that Null let's you have optional foreign/unique
> keys.

So every query, every application needs to handle the what-if the
foreign-key value is missing?  So every INNER JOIN gets turned into a
LEFT JOIN and thus all the other columns in that joined-to table must
be special-cased to handle the missing related record... joy.

> Null actually makes unique keys practical. You cannot have a default value
> on a unique constraint.

Huh?  I can't do what I DID on the example I posted?  That means I
have metric shit-tonne of applications to fix... I wonder how I'm
going to go through all those applications and fix the data that
couldn't be defaulted.... I guess that call to NewID() just seemed to
work.  Shucks.

> Some people (and am one of them) even think that null is elegant.

I think infinity is elegant too... but I don't find much application
to it in my database designs.

> So much so that Microsoft had to yield to the practical pressure to bubble
> nullity into the  .NET  valueType space

They bent to the will of people that wanted to deal with database
nulls, but not the elegence of design... which is why we now have to
litter our code with lovely constructs like:

string ownerName = record.owner.HasValue() ? record.owner.name : string.Empty;

Sexy!!!

> And by the way, I think the NullObject pattern was created to help prevent
> people from throwing NullReferenceException in the application layer.

Then you would be wrong.  The NullObject pattern exists to centralize
the logical behavior when a value is not-otherwise-set. I used it in
PL/I code in the early 80s to avoid having hundreds of places in code
to check for a null object and special case the code... and there was
no SQL, .Net or NullReferenceException in sight. The NullObject
pattern was first called that (as far as I know) by Martin Fowler,
whose design skills I have personally benefitted from in several
projects. You wouldn't believe the simplifications it allows when
writing code... no if statements, no ternary magic, not even the cool
coalescing operation need... just reference your NullObject and play
along. [1]

> not intended for storing crazy stuff in the database, otherwise, all types
> may need to be reduced to some magic value. Magic values are a poor
> replacement for 'nothingness', probably because the magic value in the first
> place is not a type of 'nothingness'.

As indeed is NULL.  It's an out-of-band special value, to be sure, but
it IS still a special value, and is a poor substitute for _why_ the
value is not there... an enumeration is far my useful for this...

> I still prefer to test before you 'dot' and that works for the goose.quark()
> as well as gander->quark() because, let's face it, gander.quark() is
> undefined and could be left as such until we approach the UI.

You would rather remember to check every time... you would rather pay
the execution speed for this check every time... you would rather
special case the behavior every time... in every UI (be it the web
site, the thick client, the XML web service, the SQL report, and the
myriad Crystal reports).  Me, I would rather establish the reasonable
convention one place... but I'm lazy and care about execution speed.

> These are personal opinions,
> however, and am sure that there are cuter opinions out there. The cutest of
> it all for me is that null unifies everything for all types, meaning one
> thing and only one thing: no value is appropriate because in there's no
> place for this thing in the space of all possible members of the alphabet of
> this set.

Cute isn't the issue, nor it NULL unifying. In fact, it's exactly the
opposite.  You cannot say two NULLs are the same... they aren't.  NULL
represents discontinuity more than unity.  Your dismissal of the use
of it is a clear indicator of someone that hasn't _actually used it_.
 Much like those that dismiss TDD as too much work don't have the
practice to see where it saves so much.

> And anytime you set a magic value with the magical powers of indicating a
> loss of existence.

I never advocated a magic number.  I said that the NullObject pattern
should be used when appropriate, and that you shoud use a flag or
enumeration when it is important to capture WHY something is
missing/not-used/not-valid... this is something NULL can't do. Ever.

> localization people,

As someone who has developed hundreds of localized programs in CP/M,
Dos, Windows, HTML, etc... I can tell you that having to scatter round
your code the check for null-substitution is MUCH harder than putting
them in one place.

> No doubt, the null enigma needs some taming ...

Part of that taming is in understand where it is broken.  Part of that
is understanding the true implications of your design's decisions.

Guess how many null-checks my social-network site's code needs?  None.
 Any idea how much faster that is? I do, I've benchmarked it.

Guess how many places I have to code the behavior of a unowned profile? One.

Guess how many places I have to enable localization of that entity?
Two (gotcha!) one in the code and one in the view that is used for
reporting (and PLEASE tell me that you don't code reports against the
actual table.... please?!?)

> Well, then, maybe that's why it takes a  college degree before people get
> unleashed to go trying these kinds of stuff on their own.

If only computer science was like that... hell, that wouldn't help...
one of the smartest coders I know, with a CS Masters, didn't know
until instructed by me why clustered indexes were good, why UPDATE
statements can READ data, and why you don't put BIT values in
indexes... college degrees mean you paid the tution and (maybe)
attended some classes...

Marc

p.s. I notice you didn't comment on my schema example... I suspect you
didn't even read it... since you didn't see the OBVIOUS defaulting of
the ID column...

[0] http://en.wikipedia.org/wiki/Null_(SQL)
[1] http://en.wikipedia.org/wiki/Null_object_pattern

-- 
"He uses statistics as a drunken man uses lamp-posts… for support
rather than illumination." Andrew Lang

Marc C. Brooks
http://musingmarc.blogspot.com
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.