views:

363

answers:

5

I am using Oracle DB. At the database level, when you set a column value to either NULL or '' (empty string), the fetched value is NULL in both cases. Is it possible to store '' (empty string) as a non NULL value in the database?

I execute this

UPDATE contacts SET last_name = '' WHERE id = '1001';

commit;

SELECT last_name, ID FROM contacts WHERE id ='1001';

LAST_NAME                  ID
------------               ------
null                       1001

Is it possible to store the last_name as a non-NULL empty string ('')?

+4  A: 

The only way to do this in oracle is with some kind of auxiliary flag field, that when set is supposed to represent the fact that the value should be an empty string.

recursive
A: 

A long time since I used Oracle, but I believe we used to use a single space ' ' to represent an empty string, then trim it after reading.

Joe
until someone needs to store a single space in the string... you'd need some kind of escape sequence or something, then you'd have to make sure all the code that works with that column knows how to interpret the special syntax :(
Jeffrey Kemp
"until someone needs to store a single space in the string" - yes of course, this only works if, for example, trailing whitespace is not significant. Which is true in many applications.
Joe
A data access layer can deliberately prefix absolutely every string with one character when running on Oracle (stripping it back off on retrieval). It's ugly as hell. But then “ugly as hell” and Oracle go well together.
bobince
+1  A: 

Oracle has a well know behavior that it silently converts "" to NULL on INSERT and UPDATE statements.

fuzzy lollipop
A: 

As far as i know Oracle does not distinguish between '' and NULL, see here.

wallenborn
A: 

Building on recursive's response:

You can set up a trigger to make life easier when you're performing inserts or updates (so that you don't have to set a flag manually).

I use a date here, but any flag would do.

  CREATE TABLE x  (mycolumn     VARCHAR2(10) NULL,
                   last_updated DATE         NULL);

  CREATE TRIGGER my_trigger
  BEFORE UPDATE OR INSERT ON x
  FOR EACH ROW
  DECLARE
  BEGIN
      IF (:NEW.mycolumn IS NOT NULL) THEN
        :NEW.last_modified := SYSDATE;
      ELSE
        :NEW.last_modified := NULL; -- Leave this out if the field cannot become unknown after being known.
      END IF;
   END;

  INSERT INTO x VALUES ('', NULL);
  INSERT INTO x VALUES ('TEST', NULL);
  INSERT INTO x VALUES ('', NULL);
  INSERT INTO x VALUES ('TEST', NULL);

  SELECT * FROM X;
idea