Insert default value when null is inserted

后端 未结 5 1215
有刺的猬
有刺的猬 2021-02-13 21:07

I have an Oracle database, and a table with several not null columns, all with default values.

I would like to use one insert statement for any data I want to insert, a

相关标签:
5条回答
  • 2021-02-13 21:16

    I think the cleanest way is to not mention them in your INSERT-statement. You could start writing triggers to fill default values but that's heavy armor for what you're aiming at.

    Isn't it possible to restructure your application code a bit? In PHP, you could construct a clean INSERT-statement without messy if's, e.g. like this:

    <?php
    $insert['column_name1'] = 'column_value1';
    $insert['column_name2'] = 'column_value2';
    $insert['column_name3'] = '';
    $insert['column_name4'] = 'column_value4';
    
    // remove null values
    foreach ($insert as $key => $value) {
      if (is_null($value) || $value=="") {
        unset($insert[$key]);
      }
    }
    
    // construct insert statement
    $statement = "insert into table (". implode(array_keys($insert), ',') .") values (:". implode(array_keys($insert), ',:') .")";
    
    // call oci_parse
    $stid = oci_parse($conn, $statement);
    
    // bind parameters
    foreach ($insert as $key => $value) {
      oci_bind_by_name($stid, ":".$key, $value);
    }
    
    // execute!
    oci_execute($stid);
    ?>
    
    0 讨论(0)
  • 2021-02-13 21:19

    The better option for performance is the first one.

    Anyway, as I understand, you don't want to repeat the insert column names and values due the difficult to make modifications. Another option you can use is to run an insert with returning clause followed by an update:

    INSERT INTO schema.my_table
        ( pk_column, other_column, not_null_column_with_default_value)
    VALUES
        (:pk_column,:other_column, :not_null_column_with_default_value)
    RETURNING not_null_column_with_default_value 
    INTO :insered_value
    

    It seems to work with PHP.

    After this you can check for null on insered_value bind variable. If it's null you can run the following update:

    UPDATE my_table
       SET not_null_column_with_default_value  = DEFAULT
     WHERE  pk_column = :pk_column: 
    
    0 讨论(0)
  • 2021-02-13 21:24

    As explained in this AskTom thread, the DEFAULT keyword will only work as a stand-alone expression in a column insert and won't work when mixed with functions or expressions such as NVL.

    In other words this is a valid query:

    INSERT INTO schema.my_table
        ( pk_column, other_column, not_null_column_with_default_value)
    VALUES
        (:pk_column,:other_column, DEFAULT)
    

    You could use a dynamic query with all rows and either a bind variable or the constant DEFAULT if the variable is null. This could be as simple as replacing the string :not_null_column_with_default_value with the string DEFAULT in your $insert.

    You could also query the view ALL_TAB_COLUMNS and use nvl(:your_variable, :column_default). The default value is the column DATA_DEFAULT.

    0 讨论(0)
  • 2021-02-13 21:25

    For those who reading it now:

    In Oracle 12c there is new feature: DEFAULT ON NULL. For example:

    CREATE TABLE tab1 (
      col1        NUMBER DEFAULT 5,
      col2        NUMBER DEFAULT ON NULL 7,
      description VARCHAR2(30)
    );
    

    So when you try to INSERT null in col2, this will automatically be 7.

    0 讨论(0)
  • 2021-02-13 21:40

    I would like to use one insert statement for any data I want to insert, and don't bother to check if the values inserted are nulls or not.

    Define your table with a default value for that column. For example:

    create table myTable
    (
      created_date date default sysdate,
      ...
    )
    tablespace...
    

    or alter an existing table:

    alter table myTable modify(created_date default sysdate);
    

    Now you (or anyone using myTable) don't have to worry about default values, as it should be. Just know that for this example, the column is still nullable, so someone could explicitly insert a null. If this isn't desired, make the column not null as well.

    EDIT: Assuming the above is already done, you can use the DEFAULT keyword in your insert statement. I would avoid triggers for this.

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