- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
I'm frist?! Brillant!
Admin
Hungarian notation sends shivers down my spine...spooky...
Admin
Remy, you poor idiot... TSQL has no If.
Admin
Nope, none at all
https://msdn.microsoft.com/en-us/library/ms182717.aspx
Admin
When the function is used in SQL it might make more sense
A comparision with NULL is always false (unless of course I compare it with IS NULL or IS NOT NULL), so comparing values becomes cumbersome when both values could be NULL
... where (colum1 = column2 and column1 is not null and column2 is not null or (column1 is null and column2 is null))
(or the very same done with IsNull).
Now we'll have to remember as well that in the SQL Standard BOOLEAN still is optional and not implemented by many RDBMS (e.g. Oracle) which might explain that the function returns either 1 or 0 instead of true or false.
if the function would have been used in a SQL Query in the form
where fnValueChanged(col1, col2, 'blah') = 1
this might explain the original usage behind the function - a not SQL happy developer who simply didn't like this and implemented his own functions to be used for comparision (there was an article about that in the past: http://thedailywtf.com/articles/ch-ch-ch-changes)
I still don't get the sense of the third (unused) parameter though....
cheers
Admin
When IsNull(@pNewValue, '') <> IsNull(@pOldValue, '') and @pNewValue Is Not Null Then 1 Else 0
That's effectively if pNewValue is set and pOldValue is Null, then this thing returns 1, else 0.
Which means that the new password can only be applied if the old password is NULL. Which, of course, shouldn't be....
When dbo.fnValueHasChanged(@LocPasswordOld, @LocPassword, NULL) = 1 then @LocPassword Else @LocPasswordOld
Admin
JonasKlose, IsNull(val, defaultval) returns val if it is not null. So the "when" works fine (IF is not supported on many situations like inside the SET as used here IIRC).
The part where it's used makes no sense though, it could just be replaced with CarPassword = @LocPassword
Admin
There is also a bug when pNewValue = '' and pOldValue is NULL: ISNULL() would return '' in both cases & the function fnValueHasChanged would return 0, so the calling SQL would set CarPassword to LocPasswordOld (NULL) instead of LocPassword ('')
Admin
In all fairness to Represser and his 'There are no tanks in Baghdad' statement, it was only introduced in 2012. Sadly he chose to pick an elitist path and make fun of someone's lack of info, when it was he who was wrong the whole time. Finally, in fairness to the code, IF statement might not have existed then but wow what a convoluted way of doing it.
Admin
How, pray tell, would you write this better?
TSQL does not provide for setting a boolean variable to the result of an expression. So you can't just say "hasChanged = valueA != valueB". You have to use a CASE statement to set the value. Yes, you could use an IF and write
but that is not clearly better than a CASE statement. For one thing it turns one SET into two, which forces the reader to check if the flag being set is the same on both branches of the IF.
If you tried to just say "oldValue != newValue", then if either one is null the return value is null, which sort of looks like false. So with "CASE WHEN oldValue!=newValue then 1 else 0 end", if one value was null and the other not null, would return 0, which is indistinguishable from "not changed".
SQL is goofy about nulls, often making simple comparisons like this a beast. Other than the unused third parameter, I don't really see a blatant flaw here.
Admin
Just to be pedantic, a comparison with null is not really "always false". SQL has trinary logic: The result of a comparison or logical operation can be true, false, or null. Any compare to null returns null, neither true nor false.
If you then just test this value, a null looks like false. But if you do further operations, the null propagates. I think the key difference is that NOT FALSE is TRUE, while NOT NULL is NULL. So for example, CASE WHEN x=y THEN 1 ELSE 0 END returns 0 if x and/or y are null. So it looks like comparing to null returns false. But CASE WHEN NOT x=y THEN 1 ELSE 0 END also returns 0 if x and/or y are null. Doing a NOT on the compare doesn't change the result to true. It looks sort of like NOT FALSE = FALSE.
And by the way, if both x and y are null, x=y returns null, not true. So CASE WHEN x=y then 1 ELSE 0 END returns 0 if both are null.
Admin
What? On this site, of all places? How was that file found?
Admin
As if the code itself was not enough of a WTF, another thing is how this function "returns int", but the value that is returned is declared as "tinyint" (same as the comment at the top states) and the value is either 0 or 1, which actually makes it a bit. Have fun with types. :)
Admin
Not suggesting that it is better, but here is a more sqly way using a self join on a table variable:
DECLARE @new NVARCHAR(20) = 'hello' DECLARE @old NVARCHAR(20) = 'different'
DECLARE @t TABLE( newVal NVARCHAR(20), oldVal NVARCHAR(20))
INSERT INTO @t ( newVal, oldVal ) VALUES ( @new, @old)
SELECT COUNT(1) FROM @t table1 INNER JOIN @t table2 ON table1.newVal = table2.oldVal
Admin
Correction: if pNewValue is set and is different from pOldValue, then this thing returns 1, else 0.
Which means that the new password will be applied whenever it is NOT NULL. Which sounds reasonable. The implementation, however, isn't the best.
Admin
"What? On this site, of all places? How was that file found?"
I'm sorry, I don't understand your comment. How was what file found? Who is talking about a file?
Admin
Hmmm. the linked web page from Microsoft says it was available in SQL 2008.
Admin
And the usage pattern given in the comment is wrong too. The function only accepts 3 parameters instead of N, with the third parameter not be used anywhere.
Admin
One of the great classics of this site is that the result of a comparison or logical operation can be true, false, or filenotfound.
Admin
The correct way to do this is:
CarPassword = ISNULL(@LocPassword, @LocPasswordOld)
Admin
yep, agree. Simple and to the point. Can't believe this is the first mention of it...
Admin
So basically use the one that is set, if both are set, use one of them by default. If neither are set, profit?
Admin
I admire how self-explanatory the name ISNULL is.
(I mean, from a Sophisticated Quirky Language, what would you expect anyway.)
Admin
Ah. I didn't catch the allusion. Yes, I remember that classic now.
Admin
Should have been as simple as: RETURN (@pNewValue IS DISTINCT FROM @pOldValue);