SQL What does IF evaluate to for NULL - sql

Hi this is a pretty basic question, but I am not able to find a definitive answer to it.
What does IF evaluate to for NULL in SQL ? What will happen in following code if fieldXYZ were NULL
IF fieldXYZ=SomeValue
//do something
ELSE
//do something else
Update:
I have found one result which suggests that NULL can be considered as falsy
https://technet.microsoft.com/en-us/library/ms182587(v=sql.110).aspx

First of all, I think your if..else statement is incomplete as you are not defining any expression for your column fieldXYZ. Generally, when you write an if..else statement, you would want to write an expression that compares your column value with something. You can explicitly check for null values if you want to handle them. Here is a gist of that syntax:
--This handles null check explicitly
IF fieldXYZ IS NOT NULL AND fieldXYZ = 'somevalue'
//do something
ELSE
//do something else
Also, if the fieldXYZ is passed a NULL value in the above statement, then the first condition is not met, so the else condition applies immediately in that scenario.Hope this helps!

(I am reluctant to answer my own question, but in absence of any solution, reposting my comment as answer)
Apparently the right way is to consider NULL as falsy.

Related

SQL: Calling REPLACE() with a NULL replacement

I've recently run into this behaviour and whilst I can work around it, I'm quite curious as to why it occurs. There doesn't seem to be much documentation explaining why this happens.
Consider the following two snippets:
SELECT REPLACE('hello world', 'world', NULL)
SELECT REPLACE('hello world', 'foobar', NULL)
Both of these examples return NULL.
I don't really understand either, but with the first one I can see how if there is indeed some caveat I'm unaware of with NULLs that this will cause the outcome we see.
But with the second example I'm completely stumped. Even if there is some strange NULL replacing behaviour, why is my string being manipulated at all? The replacement string is not found in the target string.
Read this:
https://learn.microsoft.com/en-us/sql/t-sql/functions/replace-transact-sql
It states that:
Returns NULL if any one of the arguments is NULL.
This is most certainly a result of the messed up NULL handlich in SQL Server. Everything you perform with NULL will result in NULL as well. Try SELECT 1 + NULL or 'abc' + NULL. Anyways, since you are working with a string, you should use the empty string '' instead of NULL.

Netsuite CASE WHEN expression in custom search is returning "invalid expression"

I am new to writing CASE expressions in NetSuite. I have inserted the following expression in a formula field of a custom search.
CASE WHEN {item.custitem_custid}=05 OR {item.custitem_custid}=12 THEN
({item.custitem_margin}/2)
ELSE
({item.custitem_margin}/3)
END
and getting "invalid expression as a result. I am attempting to divide the margin field value by 2 if the WHEN case is true and divide by 3 if not true. Anybody have any idea as to what is wrong with my formula?
I think you need to add parentheses:
CASE WHEN ({item.custitem_custid}=05 OR {item.custitem_custid}=12) THEN
({item.custitem_margin}/2)
ELSE
({item.custitem_margin}/3)
END
I agree with egrubaugh360 that the syntax is fine and likely the joins are not working correctly. In your forumula, just double-check the "item." portion and see what you can do.
I also agree with the NVL() recommendation, but I can also see that your denominator is 2 and 3, respectively, therefore the NVL() function won't do anything to help. PLEASE DO USE NVL() every time your denominator is an unknown value, such as from a field on your record/transaction.

VB.net Strange Conditional Statement (IF)

Was wondering if someone could lend me their expertise. Pretty new to Vb.net and have come across this conditional statement in one of our products. Could someone please confirm the validity of the statement and explain what's going on here? I've tried numerous searches, but I cannot find anything related.
If (IsDBNull(dr("someID")), "0", dr("someID")) = someID.ToString() Then
I have changed the "id" value names as it's code from a commercial product, but the ID's used were all the same variable (ints).
Thanks for any input you can offer on this!
Joe
PS: The reason I can't check this at run time is because of how the product operates.
It is an inline If statement
If(condition,iftrue,iffalse) if condition is true evaluate and return iftrue else iffalse
The If operator in VB.NET 2008 acts as a ternary operator.[ REFERENCE]
Example:
Dim foo as String = If(bar = buz, cat, dog) 'Condition satisfied then it'll return cat else dog.
The statement is checking to see if the dr("SomeID") equals the value someID.ToString. The reason the If is required is because you need to check if the dr("someID") Is Null. If it is 0 is used instead which presumably should not be equal to someID.
It is the same as doing the following:
If Not IsDBNull(dr("someID")) Then
If dr("someID").ToString = someID.ToString Then
End If
End If
I would suggest that something like this would be more appropriate (checking integer values instead of comparing strings)
If(IsDBNull(dr("someID")), 0, CInt(dr("someID"))) = someID Then
I would also suggest Turning Option Strict On as the code you posted should not compile!

SQL - CASE expression inside WHERE

I read about using the CASE expression inside the WHERE clause here:
http://scottelkin.com/sql/using-a-case-statement-in-a-sql-where-clause/
I'm trying to use this to filter results from my select statement, based on a contract number which will be passed in by the user's application. My code currently throws an error of 'Invalid parameter' no matter what is passed in. I verified SELECT/FROM are working fine, as where as a WHERE clause without a CASE expression. Here is my code.
WHERE (CASE WHEN #ContractNo = 0 THEN #ContractNo ELSE #ContractNo END =
tblContracts.ContractNo)
The redundancy of the code is for troubleshooting purposes, I'm planning on using wildcard filtering on the CASE later. I'm focusing on getting the syntax down right now. I believe this should return all records for which the parameter matches the contract number stored in the table. Any help or advice would be greatly appreciated.
Are you sure you want to do this? Your case statement ALWAYS returns #ContractNo. I think what you are looking for is this:
where
case #ContractNo
when 0 then tblContracts.ContractNo
else #ContractNo
end = tblContracts.ContractNo
The filter above says "give me the contract where the ContractNo equals the parameter, or all of them if the parameter is 0.
The previous filter only filtered where the contract number field is exactly equal to the parameter.
Regardless, you should do this instead:
where #ContractNo = 0 or #ContractNo = tblContracts.ContractNo
The logic is much easier to understand, and on top of that (don't quote me on this), the optimizer probably will work better outside of the case statement.
After reading your explanation, there's a better way to do this without CASE:
WHERE #ContractNo = 0 OR tblContracts.ContractNo = #ContractNo
This will return only matching contract numbers, unless #ContractNo is 0, in which case it will return all records.
Edit: I've just noticed that casperOne proposed the same thing. I didn't see that. Big up yourself.
Try leaving out the parentheses which are in the wrong place anyway - the right one should be after "END".
Maybe you forgot to declare #ContractNo? Is it comparable to 0 and to tblContracts.ContractNo?
Recursive's post solved my issue precisely.
I saw complaints about the clarity of my original post. In the future, what can I do to make what I'm saying more straight forward? I'm not used to phrasing questions about code, and apologize for any muddled things it had. Did I just need to provide the extended details like in my 2nd post?
Thanks again for all the help.
Move your close parenthesis to before the = like so:
WHERE (CASE WHEN #ContractNo = 0 THEN #ContractNo ELSE #ContractNo END)=tblContracts.ContractNo
I fail to see what this case statement will do though... you're returning the same thing in the event the #ContractNo = 0 or if it's not...
The correct syntax is:
Select...
...
Where(
Case
When <Condition>
Then <Return if true>
Else <Return if false>
End
) = <Whatever is being matched to the output of the case statement>
Regardless of the syntax though, your example doesn't make a lot of sense, if you're looking for all items that match or have a Contract Number of 0, then you would do:
Select...
...
Where (
#ContractNo = 0 Or
#ContractNo = tblContracts.ContractNo
)
Which seems to make far more sense than what you're attempting to use the case statement for.
Edit: I must've misread the question slightly - the missing param usually means that the parameter (in this case #ContractNo) is not declared in the scope of your query/procedure. But someone already pointed that out, so I can't take any credit for that.
The reason for the case statement, including the whole "If it's 0, give the parameter, and otherwise, just give the parameter" was to test it to try to get the syntax right. Originally, I had tried saying "If it's 0, then pass in '%', to return every value. The code I posted in there was because I kept getting 'Invalid Parameter' and figured there must be something wrong with my syntax. When I separated it into basic parameter matching like so,
WHERE #ContractNo = tblContracts.ContractNo
it returned records fine. Let me explain a bit more.
I'm pulling from a bunch of different tables, and filtering the content with information not included in the select statement (i.e. tblContracts is not having information pulled from it by Select, it's only used in Where). The user will select from a combo box which will have the different contract numbers, as well as a default value of 'All'.
I'm going to have an event for when the index of the combo box changes. If it's 'All', 0 will be passed in as a parameter and I want no filtering done. Otherwise, I just want the information for that contract number (the reason for Else #ContractNo).
Don't you mean something like this?
SELECT *
FROM tblContracts
WHERE
CASE
WHEN tblContracts.ContractNo = 0 THEN #ContractNo
ELSE tblContracts.ContractNo
END = tblContracts.ContractNo
Where #ContractNo is variable of the same datatype as tblContracts.ContractNo
Why do you even need a case statement?
WHen #ContractNo = 0 then ( 0 = tblContracts.ContractNo)
else #ContractNo then (#ContractNo = tblContracts.ContractNo)
This makes no sense since you could simply write this as
Where #contractNo = tblContracts.contractNo
Is the contract number actually a numeric or is it a string that always happens to be a numeric. Check your data types between the table and the parameter and the CASE statement (for example, "= 0" or "= '0'")
This syntax should work (it does in Oracle)
WHERE CASE WHEN tblContracts.ContractNo = 0
THEN #ContractNo
ELSE tblContracts.ContractNo
END = tblContracts.ContractNo
when you say:
I'm pulling from a bunch of different tables, and filtering the content with information not included in the select statement (i.e. tblContracts is not having information pulled from it by Select, it's only used in Where). The user will select from a combo box which will have the different contract numbers, as well as a default value of 'All'.
Then it sounds to me that should have an "Where exists" clause. since your not pulling any info out of that table?!

In how many languages is Null not equal to anything not even Null?

In how many languages is Null not equal to anything not even Null?
It's this way in SQL (as a logic language) because null means unknown/undefined.
However, in programming languages (like say, C++ or C#), a null pointer/reference is a specific value with a specific meaning -- nothing.
Two nothings are equivilent, but two unknowns are not. The confusion comes from the fact that the same name (null) is used for both concepts.
In VB6 the expression Null = Null will produce Null instead of True as you would expect.
This will cause a runtime error if you try to assign it to a Boolean, however if you use it
as the condition of "If ... Then" it will act like False. Moreover Null <> Null will also
produce Null, so:
In VB6 you could say that Null is neither equal to itself (or anything else), nor unequal!
You're supposed to test for it using the IsNull() function.
VB6 also has other special values:
Nothing for object references. Nothing = Nothing is a compile error. (you're supposed to compare it using "is")
Missing for optional parameters which haven't been given. It has no literal representation so you can't even write Missing = Missing. (the test is IsMissing(foo))
Empty for uninitialized variables. This one does test equal to itself although there's also a function IsEmpty().
... let me know if I've forgotten one
I remember being a bit disgusted with VB.
Oracle is this way.
SELECT * FROM dual WHERE NULL=null; --no rows returned
MySQL has a null-safe equality operator, <=>, which returns true if both sides are equal or both sides are null. See MySQL Docs.
In C#, Nullable<bool> has interesting properties with respect to logical operators, but the equality operator is the same as other types in that language (i.e., ((bool?)null == (bool?)null) == true).
To preserve the short-circuited behavior of the short-circuited logical operators, and to preserve consistency with the non-short-circuited logical operators, the nullable boolean has some interesting properties. For example: true || null == true. false && null == false, etc. This stands in direct contradiction with other three-valued logic languages such as ANSI SQL.
You can make ruby work that way:
class Null
def self.==(other);false;end
end
n=Null
print "Null equals nothing" if n!=Null
In SQL you would have to do something like:
WHERE column is NULL
rather than
WHERE column = NULL