Sql Server not updating records - sql-server

I know this is very silly question but I am not able to understand why sql server is not updating records having NULL value, if I run below query:
UPDATE Students SET Resultsstatus = 'Final' where Resultsstatus != 'Hidden'
I run the above queries in certain circumstances where I want to update result status as "Final" for all those students who has not result status as "Hidden". To update them, I am using above sql queries. But this query is working only for those records who has result status other than NULL.
For records where we have results status as NULL, sql server is not updating those records as "Final" using above query.
Can someone please let me know, what is wrong with above query? Why it is not updating those records who has current result status as NULL?
Thanks in advance

Because NULL does not equal and does not not-equal anything, including NULL. 1 != NULL evaluates to Unknown, not True; and as Unknown is not True, then in a WHERE the row isn't returned.
When dealing with NULL values, you need to use IS (NOT) NULL):
UPDATE dbo.Students
SET Resultsstatus = 'Final'
WHERE Resultsstatus != 'Hidden'
OR Resultsstatus IS NULL;

As well as the typical WHERE Resultsstatus != 'Hidden' OR Resultsstatus IS NULL there is another syntax you can use, which may be more performant in the presence of an index:
WHERE NOT EXISTS
(SELECT Resultsstatus
INTERSECT
SELECT 'Hidden')
This works because INTERSECT has different semantics for nulls than a regular =.
The optimizer normally elides the EXISTS and turns it into a standard comparison, with nullable semantics (similar to IS DISTINCT FROM in ANSI-SQL).
See also Paul White on this.

Related

Creating a new row in SSRS dataset SQL query to use in a report parameter

I am going round in circles with a bit of SQL and would appreciate some help.
I've looked up creating temp tables, nested Select statements (where advice seems to be to avoid these like the plague) and various uses of Case statements but I can't seem to find a solution that works. I'd say I'm beginner level for SQL.
I have a table with 10 relevant records. The query that works to return all the relevant entries in the table is:
SELECT
TblServAct.ServActId
,TblServAct.ServActName
FROM TblServAct
WHERE TblServAct.ServActExclude IS NULL
ORDER BY TblServAct.ServActName
Here is where I run into problems:
When the parameter (#YESNOActivity) = Yes, I want all the rows in the table to be returned. I have managed to do this with a CASE statement
...however when the parameter (#YESNOActivity) = No, I want ONLY ONE row to be returned which doesn't actually exist in the table (and should not be inserted into the actual table). The values that I need to insert are: ServActId = 101 and ServActName = 'Select YES in Parameter2 to filter by Service Activity'
For background, the reason I am doing this is because I have found SSRS report parameters to be especially difficult to conditionally format. I want to use the dataset above to return a message in a parameter (lets call it parameter2) that the user needs to select yes in (#YESNOActivity) in order to see the full selection list in parameter2.
If I can get this to work I can see lots of potential for re-use so all advice appreciated
Thanks
Eileen
I believe this should do the job, just include your parameter in the WHERE clause and UNION it with your own row of data.
SELECT
TblServAct.ServActId
,TblServAct.ServActName
FROM TblServAct
WHERE TblServAct.ServActExclude IS NULL
AND #YESNOActivity = 'Yes'
UNION ALL
SELECT
ServActId = 101
,ServActName = 'Select YES in Parameter2 to filter by Service Activity'
WHERE #YESNOActivity = 'No'
ORDER BY TblServAct.ServActName
One way is to use this query:
SELECT
TblServAct.ServActId
,TblServAct.ServActName
FROM TblServAct
WHERE TblServAct.ServActExclude IS NULL
AND 'Yes' = #YESNOActivity
UNION ALL
SELECT
101 AS ServActId
,'Select YES in Parameter2 to filter by Service Activity' AS ServActName
WHERE 'No' = #YESNOActivity
ORDER BY TblServAct.ServActName
Another way would be to create two data flows and use your variable in a constraint to send the processing to one or the other.
A third way would be to put an expression on the SQL command and use your variable to switch between two SQL statements.

NULL vs empty string

What is the difference between the below queries & how it works?
SELECT * FROM some_table WHERE col IS NOT NULL
&
SELECT * FROM some_table WHERE col <> ''
Regards,
Mubarak
The NULL is special data type, it means absence of value.
An empty string on the other hand means a string or value which is empty.
Both are different.
For example, if you have name field in table and by default you have set it to NULL. When no value is specified for it, it will be NULL but if you specify a real name or an empty string, it won't be NULL then, it will contain an empty string instead.
NULL is the absence of value, and usually indicates something meaningful, such as unknown or not (yet) determined. For example, if I start a project today, the StartDate is 2012-02-25. If I don't know how long the project is going to take, what should the EndDate be? I might have some idea what the ProjectedEndDate may be, but I would set the EndDate to NULL, and update it when the project is complete.
'' is a zero-length (or "empty") string. It is not technically the absence of data, since it might actually be meaningful. For example, if I don't have a middle name, depending on your data model '' might make more sense than NULL since the latter implies unknown but '' can imply that it is known that I don't have one. NULL can be used the same way of course, but then it is difficult to decipher whether it is not known whether it exists, or known that it does not exist. A lot of standards have dedicated values for things where it might not be known - for example Gender has I believe 9 different character codes so that if M or F are not specified, we always know exactly why (unknown, unspecified, transgender, etc). Also think of the case where HeartRate is NULL - is it because there was no pulse, or because we haven't taken it yet?
They are not the same, though unfortunately many people treat them the same. If your column allows NULL it means that you know in advance that sometimes you may not know this information. If you are not treating them as the same thing, then your queries would differ. For example if col does not allow NULL, your first query will always return all results in the table, since none of them can be NULL. However NOT NULL still allows an empty string to be entered unless you have also set up a check constraint to prevent zero-length strings also.
Allowing both for the same column is usually a bit confusing for someone trying to understand the data model, though I believe in most cases a NOT NULL constraint is not combined with a LEN(col)>0 check constraint. The problem if both are allowed is that it is difficult to know what it means if the column is NULL or the column is "empty" - they could mean the same thing, but they may not - and this will vary from shop to shop.
Another key point is that NULL compared to anything (at least by default in SQL Server*) evaluates to unknown, which in turn evaluates to false. As an example, these queries all return 0:
DECLARE #x TABLE(i INT);
INSERT #x VALUES(NULL);
SELECT COUNT(*) FROM #x WHERE i = 1;
SELECT COUNT(*) FROM #x WHERE i <> 1;
SELECT COUNT(*) FROM #x WHERE i <= 3;
SELECT COUNT(*) FROM #x WHERE i > 3;
SELECT COUNT(*) FROM #x WHERE i IN (1,2,3);
SELECT COUNT(*) FROM #x WHERE i NOT IN (1,2,3);
Since the comparisons in the where clause always evaluate to unknown, they always come back false, so no rows ever meet the criteria and all counts come back as 0.
In addition, the answers to this question on dba.stackexchange might be useful:
https://dba.stackexchange.com/questions/5222/why-shouldnt-we-allow-nulls
* You can change this by using SET ANSI_NULLS OFF - however this is not advised both because it provides non-standard behavior and because this "feature" has been deprecated since SQL Server 2005 and will become a no-op in a future version of SQL Server. But you can play with the query above and see that the NOT IN behaves differently with SET ANSI_NULLS OFF.
NULL means the value is missing but '' means the value is there but just empty string
so first query means query all rows that col value is not missing, second one means select those rows that col not equals empty string
Update
For further information, I suggest you read this article:
https://sqlserverfast.com/blog/hugo/2007/07/null-the-databases-black-hole/
Select * from table where col IS NOT NULLwould return results excluded from Select * from table where col <> ‘’ because an empty string is also NOT NULL.
https://data.stackexchange.com/stackoverflow/query/62491/http-stackoverflow-com-questions-9444638-null-vs-empty-in-sql-server
SET NOCOUNT ON;
DECLARE #tbl AS TABLE (value varchar(50) NULL, description varchar(50) NOT NULL);
INSERT INTO #tbl VALUES (NULL, 'A Null'), ('', 'Empty String'), ('Some Text', 'A non-empty string');
SELECT * FROM #tbl;
SELECT * FROM #tbl WHERE value IS NOT NULL;
SELECT * FROM #tbl WHERE value <> '';
Note that in the display you cannot distinguish between NULL and '' - this is only an artifact of how the grid and text client display the data, but the data in the set is stored differently for NULL and ''.
As stated in other answers, NULL means 'no value' while empty string '' means just that - empty string. You can think of fields that allow NULLs as optional fields - they can be ignored and value for them may just not be provided.
Imagine an application where respondent selects their title (Mr, Mrs, Miss, Dr) but you do not require him/her to select any of those and leave it blank. In this case you would put NULL into relevant database field.
Distinction between NULL and empty string may not be obvious because they both can mean 'no value' if you decide to. It depends entirely up to you but using NULL would be better mainly because it is a special case for databases which are designed to handle NULLs quickly and efficiently (much faster than strings). If you use it instead of an empty string your queries will be faster and more reliable.

How do I select if a column is null or not (as a boolean)

I'm making a database view in MS SQL server 2008 R2. One of the output columns, named 'Status', pulls information about an entity from several different tables to produce a string status that is reported to the user.
I'm therefore creating a function which takes the entity ID as the only parameter and returns the nvarchar(MAX) status.
The first check is whether or not the entity has been approved. This is stored in the database as the username of the person that approved it. If it is not approved, the value is NULL.
So, pseudo-code for what I want to do is this:
if entity is NOT approved
return "Pending"
else
begin
max = select MAX(value) from EntityStatus // several statuses may exist
status = select name from EntityStatus WHERE value = max
return status
end
My immediate problem is: How do I select the 'approved' boolean?
I'm very new to T-SQL programming (it probably shows) so feel free to suggest other ways I can improve my function.
if (select approver_username from approvals where entityid = #entityid) is null
return 'Pending'
else
begin
...
end
try this
select city,isnull(city,'pending/unknown')city2 from authors

MyNullableCol <> 'MyValue' Doesn't Includes Rows where MyNullableCol IS NULL

Today I found a strange problem that is I have a Table With a Nullable Column and I tried to use following Query
SELECT *
Id,
MyNCol,
FROM dbo.[MyTable]
WHERE MyNCol <> 'MyValue'
And Expecting it to return all rows not having 'MyValue' value in Field MyNCol. But its not returning all those Rows Containing NULL in above specified Column(MyNCol).
So I have to Rewrite my query to
SELECT *
Id,
MyNCol,
FROM dbo.[MyTable]
WHERE MyNCol <> 'MyValue' OR MyNCol IS NULL
Now My question is why is it why the first query is not sufficient to perform what i desire. :(
Regards
Mubashar
Look into the behaviour of "ANSI NULLs".
Standardly, NULL != NULL. You can change this behaviour by altering the ANSI NULLS enabled property on your database, but this has far ranging effects on column storage and query execution. Alternatively, you can use the SET ANSI_NULLS statement in your SQL script.
MSDN Documentation for SQL Server 2008 is here:
SET ANSI_NULLS (Transact-SQL)
Pay particular attention to the details of how comparisons are performed - even when setting ANSI_NULLS OFF, column to column comparisons may not behave as you intended. It is best practice to always use IS NULL and IS NOT NULL.
Equality operators cannot be performed on null values. In SQL 2000, you could check null = null, however in 2005 this changed.
NULL = UNKNOWN. So you can neither say that MyNCol = 'My Value' nor that MyNCol <> 'My Value' - both evaluate to UNKNOWN (just like 'foo' + MyNCol will still become NULL). An alternative to the workaround you posted is:
WHERE COALESCE(MyNCol, 'Not my Value') <> 'My Value';
This will include the NULL columns because the comparison becomes false rather than unknown. I don't like this option any better because it relies on some magic value in the comparison, even though that magic value will only be supplied when the column is NULL.

Is there a setting in SQL Server to have null = null evaluate to true?

Is there a setting in SQL Server to have null = null evaluate to true?
It is not SQL Server's fault, it is due to the ternary logic introduced by the NULL value. null=null will never be true, and null <> null is not true either.
you could use ANSI_NULL OFF but:
"In a future version of SQL Server, ANSI_NULLS will always be ON and any applications that explicitly set the option to OFF will generate an error. Avoid using this feature in new development work, and plan to modify applications that currently use this feature."
Wouldn't COALESCE do what you need?
From the MSDN Documentation:
SET ANSI_NULLS OFF
Will create the following comparison results:
10 = NULL False
NULL = NULL True
10 <> NULL True
NULL <> NULL False
With the following setting, which is the default:
SET ANSI_NULLS ON
The same comparisons will give these results:
10 = NULL NULL (Unknown)
NULL = NULL NULL (Unknown)
10 <> NULL NULL (Unknown)
NULL <> NULL NULL (Unknown)
Edit: Ok, so per comments, I tried some specific SQL to verify the claims that this did not work, and here's what I found:
SET ANSI_NULLS OFF
CREATE TABLE TestTable (USERNAME VARCHAR(20))
INSERT INTO TestTable VALUES (NULL)
SELECT * FROM TestTable WHERE USERNAME = USERNAME
SELECT * FROM TestTable WHERE USERNAME = NULL
Produces this output:
[USERNAME]
(0 row(s) affected)
[USERNAME]
NULL
(1 row(s) affected)
So I guess this setting is flawed. I've only seen and used this setting in one particular reporting query so I wasn't aware of the difference in query plans that makes it work in one instance and not in another.
Then there is no setting that works.
Even if it did work, as per other answers here, relying on this setting is a bad idea since it will be yanked out from SQL Server in a future version.
Oh well.
Yeah turning that off doesn't seem good in general.
I am just mentioned this in case you are doing a comparison where you first object might not be a null in the comparison:
val IS NULL can be used to test if something is null or not.
NULL = NULL should be False because Unknown = Unknown is Unknown or False.
I will avoid the ansi_nulls setting and use isnull function although it could complicate certain queries.
We're possibly dealing with this at the wrong level of abstraction. It appears that you have a query where you've stated it in such a fashion that you aren't getting the result you expect. So you've asked a question about how to change the database so it will give you what you expect, rather than what the database understood.
Wouldn't it be better to ask about how to restate your query so the database understands it as you intended?
Then you finish off with the assertion that it will complicate other queries. I think there was a general reacion of "ouch" from a lot of us who read that. because, given your apparent understanding of NULLs, that's probably true.
We might be able to help us discuss the your understanding of NULLs, if you would tell us what it is that you think will cause these problems.

Resources