Oracle considers empty strings to be NULL while SQL Server does not - how is this best handled?

前端 未结 11 1788
挽巷
挽巷 2021-01-01 13:35

I have to write a component that re-creates SQL Server tables (structure and data) in an Oracle database. This component also has to take new data entered into the Oracle d

相关标签:
11条回答
  • 2021-01-01 13:56

    NOT NULL is a database constraint used to stop putting invalid data into your database. This is not serving any purpose in your Oracle database and so I would not have it.

    I think you should just continue to allow NULLS in any Oracle column that mirrors a SqlServer column that is known to contain empty strings.

    If there is a logical difference in the SqlServer database between NULL and empty string, then you would need something extra to model this difference in Oracle.

    0 讨论(0)
  • 2021-01-01 13:57

    Well, main point I'd consider is absence of tasks when some field can be null, the same field can be empty string and business logic requires to distinguish these values. So I'd make this logic:

    • check MSSQL if column has NOT NULL constraint
    • check MSSQL if column has CHECK(column <> '') or similar constraint

    If both are true, make Oracle column NOT NULL. If any one is true, make Oracle column NULL. If none is true, raise INVALID DESIGN exception (or maybe ignore it, if it's acceptable by this application).

    When sending data from MSSQL to Oracle, just do nothing special, all data would be transferred right. When retrieving data to MSSQL, any not-null data should be sent as is. For null strings you should decide whether it should be inserted as null or as empty string. To do this you should check table design again (or remember previous result) and see if it has NOT NULL constraint. If has - use empty string, if has not - use NULL. Simple and clever.

    Sometimes, if you work with unknown and unpredictable application, you cannot check for existence of {not empty string} constraint because of various forms of it. If so, you can either use simplified logic (make Oracle columns always nullable) or check whether you can insert empty string into MSSQL table without error.

    0 讨论(0)
  • 2021-01-01 13:59

    If you are migrating data you might have to substitute a space for an empty string. Not very elegant, but workable. This is a nasty "feature" of Oracle.

    0 讨论(0)
  • 2021-01-01 14:03

    Although, for the most part, I agree with most of the other responses (not going to get into an argument about any I disagree with - not the place for that :) )

    I do notice that OP mentioned the following:

    "Oracle considers a blank string to be the same as a NULL value, so if a char column is defined as NOT NULL, you cannot insert a blank string."

    Specifically calling out CHAR, and not VARCHAR2. Hence, talking about an "empty string" of length 0 (ie '' ) is moot. If he's declared the CHAR as, for example, CHAR(5), then just add a space to the empty string coming in, Oracle's going to pad it anyway. You'll end up with a 5 space string.

    Now, if OP meant VARCHAR2, well yeah, that's a whole other beast, and yeah, the difference between empty string and NULL becomes relevant.

      SQL> drop table junk;
    
      Table dropped.
    
      SQL>
      SQL> create table junk ( c1     char(5) not null );
    
      Table created.
    
      SQL>
      SQL> insert into junk values ( 'hi' );
    
      1 row created.
    
      SQL>
      SQL> insert into junk values ( ' ' );
    
      1 row created.
    
      SQL>
      SQL> insert into junk values ( '' );
      insert into junk values ( '' )
                                *
      ERROR at line 1:
      ORA-01400: cannot insert NULL into ("GREGS"."JUNK"."C1")
    
    
      SQL>
      SQL> insert into junk values ( rpad('', 5, ' ') );
      insert into junk values ( rpad('', 5, ' ') )
                                *
      ERROR at line 1:
      ORA-01400: cannot insert NULL into ("GREGS"."JUNK"."C1")
    
    
      SQL>
      SQL> declare
        2    lv_in   varchar2(5) := '';
        3  begin
        4     insert into junk values ( rpad(lv_in||' ', 5) );
        5  end;
        6  /
    
      PL/SQL procedure successfully completed.
    
      SQL>
    
    0 讨论(0)
  • 2021-01-01 14:04

    Its nasty and could have unexpected side effects.. but you could just insert "chr(0)" rather than ''.

    drop table x
    
    drop table x succeeded.
    create table x ( id number, my_varchar varchar2(10))
    
    create table succeeded.
    insert into x values (1, chr(0))
    
    1 rows inserted
    insert into x values (2, null)
    
    1 rows inserted
    select id,length(my_varchar) from x
    
    ID                     LENGTH(MY_VARCHAR)     
    ---------------------- ---------------------- 
    1                      1                      
    2                                             
    
    2 rows selected
    
    select * from x where my_varchar is not null
    
    ID                     MY_VARCHAR 
    ---------------------- ---------- 
    1                      
    
    0 讨论(0)
  • 2021-01-01 14:06

    Do you have to permit empty strings in the SQL Server system? If you can add a constraint to the SQL Server system that disallows empty strings, that is probably the easiest solution.

    0 讨论(0)
提交回复
热议问题