Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this implementation SQL-92 conformant?

Tags:

sql

oracle

plsql

Tony Andrews in another question gave an example of:

IF p_c_courtesies_cd 
   || p_c_language_cd 
   || v_c_name 
   || v_c_firstname 
   || v_c_function 
   || p_c_phone 
   || p_c_mobile p_c_fax 
   || v_c_email is not null
THEN
     -- Do something
END IF;

as a clever (if not a tad obscure) alternative to the Oracle COALESCE function. Sure enough, it works, if any argument is not null, the IF test is true. My question: Is Oracle's implementation of the above concatenation operation SQL-92 conforming? Shouldn't an expression involving a NULL evaluate to NULL? If you don't think so, then why should the expression 1 + NULL evaluate to NULL?

like image 298
DCookie Avatar asked Jan 20 '09 18:01

DCookie


People also ask

How many pages does the SQL-92 have?

The SQL-92 standard had almost 600 pages, but it was still accessible to regular SQL users. Books like A Guide to the SQL Standard by Christopher Date and Hugh Darwen discussed and explained the SQL-92 standard.

What are the three levels of conformance of the SQL standard?

Starting with SQL:1999, the SQL standard defines a large set of individual features rather than the three levels (Entry, Intermediate and Full) declared in SQL-92. A large subset of these features represents the "Core" (mandatory) features, SQL implementation must supply in order to claim conformance.


3 Answers

No, Oracle's treatment of nulls is idiosyncratic, different from everyone else's, and inconsistent with the ANSI standards. In Oracle's defence however, it probably settled on and was committed to this treatment long before there was an ANSI standard to be consistent with!

It all starts from the fact that Oracle stores strings with a character count followed by the string data. A NULL is represented by a character count of zero with no following string data - which is exactly the same as an empty string (''). Oracle simply doesn't have a way to distinguish them.

This leads to some quirky behaviour, such as this concatenation case. Oracle also has a function LENGTH to return the length of a string, but this has been defined in an opposite manner, so that LENGTH('') returns NULL not zero. So:

LENGTH('abc') + LENGTH('') IS NULL

LENGTH('abc' || '') = 3

which seems to me to violate basic mathematical principles.

Of course, Oracle developers become so used to this that many of us can't even see anything wrong or odd about it - some will in fact argue that the rest of the world is wrong and that an empty string and a NULL are the same thing!

like image 71
Tony Andrews Avatar answered Oct 22 '22 14:10

Tony Andrews


@Nezroy: Thanks for the link. As I read the standard, however, I believe it states that Oracle's implementation is in fact, incorrect. Section 6.13, General Rules, item 2a:

     2) If <concatenation> is specified, then let S1 and S2 be the re-
        sult of the <character value expression> and <character factor>,
        respectively.

        Case:

        a) If either S1 or S2 is the null value, then the result of the
          <concatenation> is the null value.
like image 42
DCookie Avatar answered Oct 22 '22 14:10

DCookie


Based on the portion of the SQL-92 spec highlighted by DCookie and the behavior of other DBs, I'd say Oracle is not behaving to standard with their concatenation operator.

Oracle (from tuinstoel's answer):

SQL>  select 'something'||null from dual;

'SOMETHIN
---------
something

MSSQL:

SELECT 'something'+NULL;

NULL

PostgreSQL:

postgres=# \pset null '(null)'
Null display is "(null)".
postgres=# select 'something'||null as output;
 output
--------
 (null)
(1 row)

MySQL:

mysql> select concat('something',NULL) as output;
+--------+
| output |
+--------+
| NULL   |
+--------+
1 row in set (0.00 sec)
like image 1
nezroy Avatar answered Oct 22 '22 14:10

nezroy