Can I insert an empty string in a NOT NULL field? - sql

Can I insert an empty string in a not null field?
insert into xyz(A,B) values(1,''); // is this possible if B is NOT NULL?

Depends on DBMS.
Oracle no: '' and null are identical
SQL-Server yes: '' and null are different values.

Yes you can... The concept of the NULL value is a common source of confusion for newcomers to SQL, who often think that NULL is the same as an empty string '', or a value of zero.
This is not the case. Conceptually, NULL means "a missing unknown value" and it is treated somewhat differently from other values. For example, to test for NULL, you cannot use the arithmetic comparison operators such as =, <, or <> in most DBMSes.

As Daniel said, yes you can insert the zero-length string into a NOT NULL field (except on Oracle). However, if you want to rule out zero-length strings as well, you can add a constraint:
ALTER TABLE xyz ADD CONSTRAINT CHECK (b LIKE '_%');
Most modern databases have a regular-expression operator or function you could use for constraints as well, but the exact syntax varies from database to database.

Related

Difference between "=" and "is" in sql server

I am having problem while understanding = and is operators in SQL Server.
Consider the following example queries which are having different behaviors in their respective output:
SELECT * FROM tableName WHERE colName IS NULL;
SELECT * FROM tableName WHERE colName = NULL;
First query will provide the required output i.e. select those records for which colName is having a null value. But the second query will result in zero matching records.
Please clarify different uses of these operators with pros and cons.
EDIT
Here, most of the answers are claiming that = doesn't work with null, but the following statement will work with null and =.
SET ANSI_NULLS OFF
SELECT * FROM tableName WHERE colName = NULL;
This will provide the same result as statement having is operator.
Nothing equals null.
Not even null equals null.
null is not a value, it is more like a concept, or a mark, meaning unknown value.
As such, you need two operators for this, one for equality, and one for checking the concept of null.
Once you start to think of null as "unknown value" a lot of the other behavior also makes sense.
10 + null? Add an unknown value to 10? Obviously you will have another unknown value as a result.
For more information, please check the documentation of the equality operator in T-SQL.
Additionally, see the documentation for SET ANSI_NULL.
Note that the documentation is in conflict about the behavior of x = null between the equality operator (documentation says it will always be false if x is non-null) whereas SET ANSI_NULLS documentation says that x = null will behave equivalent to x is null when the option is turned on.
From http://msdn.microsoft.com/en-us/library/ms188795.aspx:
To determine whether an expression is NULL, use IS NULL or IS NOT NULL instead of comparison operators (such as = or !=). Comparison operators return UNKNOWN when either or both arguments are NULL.
EDIT
The originating question was updated to note that SET ANSI_NULLS OFF allows:
select * from tableName where colName = null.
This may be true at the moment but future versions of SQL server will set ANSI_NULLS always ON and any calls to SET ANSI_NULLS OFF will result in an error.
Source: http://msdn.microsoft.com/en-us/library/ms188048.aspx
= NULL is always unknown (this is piece of 3 state logic), but WHERE clause treats it as false and drops from the result set. So for NULL you should use IS NULL
= NULL is used for assignment to a NULL value whereas IS NULL is used to determine whether a variable is NULL-valued.
See these articles on null
Wikipedia NUll (SQL)
w3schools SQL NULL Values
SQL Tutorial, see IS NULL Operator section
Null is not same as zero. Null is absence of value. It simply means that the value could be anything. It is unknown.
Q. Why select * from tableName where colName = null returns zero rows?
A. Because you can not be sure that one null(unknown value) is equal to or not equal to another null(another unknown value).
EG:
I have a magic hat and nobody knows what will come out of it(if anything comes out at all).
You have another magic hat and nobody knows what will come out of it(if anything comes out at all).
We both have a magic hat each and what it has inside is unknown (null).
These both hats could contain a rabbit each or may be my hat contains a hammer and your's has a pineapple.
If you have an if condition like this..
if(#flag<>null)
it is a mistake because if you pass null to #flag you do not really know whether or not #flag is equal or not equal to null
Use if(#flag<>isnull(null,'')) instead

PL/SQL Oracle condition equals

I think I'm encountering a fairly simple problem in PL/SQL on an Oracle Database(10g) and I'm hoping one of you guys can help me out.
I'm trying to explain this as clear as possible, but it's hard for me.
When I try to compare varchar2 values of 2 different tables to check if I need to create a new record or I can re-use the ID of the existing one, the DB (or I) compares these values in a wrong way. All is fine when both the field contain a value, this results in 'a' = 'a' which it understands. But when both fields are NULL (or '' which Oracle will turn into NULL) it can not compare the fields.
I found a 'solution' to this problem but I'm certain there is a better way.
rowTable1 ROWTABLE1%ROWTYPE;
iReUsableID INT;
SELECT * INTO rowTable1
FROM TABLE1
WHERE TABLE1ID = 'someID';
SELECT TABLE2ID INTO iReUsableID
FROM TABLE2
WHERE NVL(SOMEFIELDNAME,' ') = NVL(rowTable1.SOMEFIELDNAME,' ');
So NVL changes the null value to ' ' after which it will compare in the right way.
Thanks in advance,
Dennis
You can use LNNVL function (http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions078.htm) and reverse the condition:
SELECT TABLE2ID INTO iReUsableID
FROM TABLE2
WHERE LNNVL(SOMEFIELDNAME != rowTable1.SOMEFIELDNAME);
Your method is fine, unless one of the values could be a space. The "standard" way of doing the comparison is to explicitly compare to NULL:
WHERE col1 = col2 or col1 is null and col2 is null
In Oracle, comparisons on strings are encumbered by the fact that Oracle treats the empty string as NULL. This is a peculiarity of Oracle and not a problem in other databases.
In Oracle (or any RDBMS I believe), one NULL is not equal to another NULL. Therefore, you need to use the workaround that you have stated if you want to force 2 NULL values to be considered the same. Additionally, you might want to default NULL values to '' (empty) rather than ' ' (space).
From Wikipedia (originally the ISO spec, but I couldn't access it):
Since Null is not a member of any data domain, it is not considered a "value", but rather a marker (or placeholder) indicating the absence of value. Because of this, comparisons with Null can never result in either True or False, but always in a third logical result, Unknown.
As mentioned by Jan Spurny, you can use LNNVL for comparison. However, it would be wrong to say that a comparison is actually being made when both values being compared are NULL.
This is indeed a simple and usable way to compare nulls.
You cannot compare NULLS directly since NULL is not equal NULL.
You must provide your own logic who you would like to compare, what you've done with NVL().
Take in mind, you are treating NULLS as space, so ' ' in one table would be equal to NULL in another table in your case.
There are some other ways (e.g. LNNVL ) but they are not some kind of a "better" way, I think.

SQL Statement to set NULL Values to initialized values

In SQL or T-SQL how can I go through a table and set fields that are NULL to empty strings if the type is textual and 0 if the fields are integer types.
Thanks for any help, I do not even know where to begin.
Well if it's just one table use a basic update query:
UPDATE MyTable
SET NumericColumn = ISNULL(NumericColumn,0),
StringColumn= ISNULL(StringColumn,'')
What you're suggesting would only work as a "one off".
If you always want those fields to be populated going forward you can set a default value on the table.
You can use IsNull function in T-SQL,
Syntax :
ISNULL ( check_expression , replacement_value )
The function coalesce( expression_1 , expression_2 , ... ) is also useful in this context.
It evaluates the specified expressions from left to right and returns the value of the first expression that evaluates to a value other than null, or null if all the specified expressions evaluate to null.
This can be useful, especially in conjunction with left joins and table rotations.

(NOT) NULL for NVARCHAR columns

Allowing NULL values on a column is normally done to allow the absense of a value to be represented. When using NVARCHAR there is aldready a possibility to have an empty string, without setting the column to NULL. In most cases I cannot see a semantical difference between an NVARCHAR with an empty string and a NULL value for such a column.
Setting the column as NOT NULL saves me from having to deal with the possibility of NULL values in the code and it feels better to not have to different representations of "no value" (NULL or an empty string).
Will I run into any other problems by setting my NVARCHAR columns to NOT NULL. Performance? Storage size? Anything I've overlooked on the usage of the values in the client code?
A NULL indicates that the value in the column is missing/inapplicable. A blank string is different because that is an actual value. A NULL technically has no data type where as a blank string, in this case, is nvarchar.
I cant see any issues with having default values rather than NULL values.
In fact, it would probably be beneficial as you wouldn't have to worry about catering for NULL values in any of your queries
e.g
Select Sum(TotalPrice) as 'TotalPrice' From myTable Where CountOfItems > 10
much easier than
Select Sum(IsNull(TotalPrice,0)) as 'TotalPrice' From myTable Where IsNull(CountOfItems,0) > 10
You should use default constraints in your DDL to ensure that no rogue NULL's appear in your data.
The concept of the NULL value is a common source of confusion. NULL is not the same as an empty string, or a value of zero.
Conceptually, NULL means "a missing unknown value" and it is treated somewhat differently from other values. For example, to test for NULL, you cannot use the arithmetic comparison operators such as =, <, or <>.
If you have columns that may contain "a missing unknown value", you have to set them to accept NULLs. On the other hand, an empty string simply means that the value is known, but is empty.
For example: If a "Middle Name" field in a "Users" table is set to NULL, it should mean that the middle name of that user is not known. The user might or might not have a middle name. However, if the "Middle Name" field is set to an empty string, this should mean that the user is known to have no middle name.
If anything I'd say that it'll be easier to use the table if you don't allow NULLs, since you won't have to check for NULLs everywhere in code, so I'd only set a column to allow NULLs if I need to handle unknown rather than empty values.
What ho1 said. But you'd be ill-advised to define a column NOT NULL and then have a special value for 'Unknown'.

SQL: Why are NULL values filtered out within this where clause?

In my table, I have a nullable bit column (legacy system...) and another developer recently made a change to a stored procedure to only show values where the bit column was not true (1). Because this is a nullable column, we noticed that if the column was NULL, the record was not being picked up. WHY is this?
Both the other developer and I agree that NULL <> 1... Is this a bug in SQL or was this designed this way? Seems like a design flaw.
Current Code:
(VoidedIndicator <> 1)
Proposed Fix:
(VoidedIndicator <> 1 OR VoidedIndicator IS NULL)
Clarification (By Jon Erickson)
VoidedIndicator is a nullable bit field so it can have the following values: NULL, 0, or 1
When a SQL statement is created with a where clause such as (VoidedIndicator <> 1) we only get records returned that have VoidedIndicator == 0, but we were expecting both VoidedIndicator == 0 and VoidedIndicator IS NULL. Why is this?
Lots of good answers, but let me give you a really concise version.
To SQL, Null does NOT mean "No value" it means "Unknown Value"
With that in mind, consider the answer to the question you are asking SQL in plain English.
Q: Is this unknown value not equal to 1?
A: I don't know, there is no way to tell without knowing the value.
Hence Null<>1 = Null
From the Wikipedia entry on NULL:
For example, a WHERE clause or
conditional statement might compare a
column's value with a constant. It is
often incorrectly assumed that a
missing value would be "less than" or
"not equal to" a constant if that
field contains Null, but, in fact,
such expressions return Unknown. An
example is below:
-- Rows where num is NULL will not be returned,
-- contrary to many users' expectations.
SELECT * FROM sometable WHERE num <> 1;
Basically, any comparison between NULL and something else, whether it's with = or <> will not be true.
As another reference, the MSDN T-SQL page on <> states:
Compares two expressions (a comparison
operator). When you compare nonnull
expressions, the result is TRUE if the
left operand is not equal to the right
operand; otherwise, the result is
FALSE. If either or both operands are
NULL, see SET ANSI_NULLS
(Transact-SQL).
The SET ANSI_NULLS page then states:
When SET ANSI_NULLS is ON, a SELECT
statement that uses WHERE column_name
= NULL returns zero rows even if there are null values in column_name. A
SELECT statement that uses WHERE
column_name <> NULL returns zero rows
even if there are nonnull values in
column_name.
...
When SET ANSI_NULLS is ON, all
comparisons against a null value
evaluate to UNKNOWN. When SET
ANSI_NULLS is OFF, comparisons of all
data against a null value evaluate to
TRUE if the data value is NULL.
It's not a bug.
NULL is not equal to anything, not even NULL (NULL = NULL returns FALSE).
Typically NULL values aren't indexed either. It's generally a bad idea to rely on a particular value or NULL. Depending on what you're storing in the column, you may be better off putting a dummy or sentinel value in rather than using NULL to indicate some meaning.
The other folks are correct that NULL <> 1 doesn't evaluate as true, therefore it doesn't satisfy the WHERE clause.
The proposed fix you describe is the best way of handling it:
(VoidedIndicator <> 1 OR VoidedIndicator IS NULL)
SQL-99 does have a predicate that helps in this case, called IS DISTINCT FROM:
(VoidedIndicator IS DISTINCT FROM 1)
This predicate would behave exactly the same as your proposed fix. Unfortunately, Microsoft SQL Server does not support IS DISTINCT FROM yet.
You can also: isnull(VoidedIndicator,1) <> 1
Because the WHERE clause only selects rows when the condition evaluates to true.
When one of the operands is NULL, the condition usually evaluates to UNKNOWN (approximately equivalent to NULL), and therefore is not true. It applies to both 'column = 1' and 'column <> 1'; if column is NULL, the search condition fails.
It is why you get told to avoid NULL columns whenever possible.
NULL <> 1 evaluates (theoretically) to "maybe", which means the record will not be returned.