DaBozUK
DaBozUK

Reputation: 610

Why does SQLPLUS show empty and null CLOBs as null?

It seems SQLPLUS shows nulls and empty strings for CLOBs in a way that I wasn't expecting.

Try the following in SQLPLUS (I'm using Oracle 10g Server). Create a table with a CLOB, and insert null, empty clob, and what I think of as an empty string:

create table tableA (field1 number, field2 clob);
insert into tableA values (1, null);
insert into tableA values (2, empty_clob());
insert into tableA values (3, '');

OK, lets do some queries, but first we need to tell SQLPLUS to show nulls clearly for us:

set null {NULL}

For the following query, I would have expected only row 1 returned, but it returns 2:

select * from tableA where field2 is null;

field1   field 2
-----------------------
1        {NULL} 
3        {NULL} 

Hmm, so '' is stored as a null in a CLOB?

Ok, so based on that result, I would now expect the following query to return all 3 rows but show {NULL} in rows 1 and 3 only. However I get this result:

select * from tableA;

field1   field 2
-----------------------
1        {NULL} 
2        {NULL} 
3        {NULL} 

This is confusing. I thought there were only 2 nulls, even though I originally expected 1. So what's going on here? Does set null not work for CLOBs, and if so what should I use instead?

I'm actually trying to solve a different problem with null CLOB values, but this confusing behaviour has had me running rings for a while, so I'd like to understand this before I continue.

Thanks in advance

Boz

Upvotes: 4

Views: 3815

Answers (3)

user330315
user330315

Reputation:

I think it's something to do with the way SQL*Plus handles empty strings and null values.

empty_clob() does not create a NULL value, but a CLOB of length zero.

Which is proven by the fact that row 2 is is not returned when you query for rows where field2 is null.

With my JDBC tool I can highlight columns that are null with a different color, and there the row with the empty_clob() is not highlighted whereas the other two are.

So I'd say it's a wrong handling of the set null option in SQL*Plus. With the following statement you will see the difference:

select field1, 
       nvl(field2, 'THIS IS NULL')
from tableA;

For me this displays:

field1   field 2
-----------------------
1        THIS IS NULL 
2        
3        THIS IS NULL

Upvotes: 4

Tom Hubbard
Tom Hubbard

Reputation: 16129

It would be interesting to see what is really in row 2. It may not truly be null as according to the documentation (see below) empty_clob() will return a initialized clob locate that does not have data (somewhat unclear on the null issue).

When executing SQL statements in SQL query tools though Oracle tends to implicitly convert CLOB's to strings which are cut off at some arbitrary length.

Purpose

EMPTY_BLOB and EMPTY_CLOB return an empty LOB locator that can be used to initialize a LOB variable or, in an INSERT or UPDATE statement, to initialize a LOB column or attribute to EMPTY. EMPTY means that the LOB is initialized, but not populated with data.

Upvotes: 2

Quassnoi
Quassnoi

Reputation: 425341

Oracle does not distinguish between NULL and an empty string. This is a well-known violation or SQL standards.

This is the reason of default string type being VARCHAR2 and not VARCHAR.

In all currently released versions they are the same, but VARCHAR is not recommended for use. This is because VARCHAR is supposed to distinguish between NULL and an empty string, while VARCHAR2, not being described in the standards, is not.

Upvotes: 8

Related Questions