插入null时插入默认值

时间:2011-03-22 08:55:35

标签: oracle default notnull

我有一个Oracle数据库和一个包含多个非空列的表,所有这些都具有默认值。

我想对我要插入的任何数据使用一个insert语句,并且不用费心去检查插入的值是否为空。

插入null时,有没有办法回退到默认列值?

我有这段代码:

<?php
if (!empty($values['not_null_column_with_default_value'])) {
    $insert = "
        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)
     ";
} else {
    $insert = "
        INSERT INTO schema.my_table
            ( pk_column, other_column)
        VALUES
            (:pk_column,:other_column)
     ";        
}

所以,我必须完全省略该列,否则我将错误“尝试将null插入非空列”。 当然我有多个可以为空的列,所以代码创建插入语句是非常难以理解的,丑陋的,我只是不喜欢它。

我想有一个声明,类似于:

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

这当然是一个假设的查询。你知道我用Oracle DBMS实现这个目标的任何方式吗?

修改

谢谢大家的回答。它接触到没有“标准”方式来实现我想要的东西,所以我接受了IMO的最佳答案:我应该停止聪明并坚持通过自动构建的语句省略空值。

不完全是我想看到的,但没有更好的选择。

5 个答案:

答案 0 :(得分:14)

对于那些现在阅读的人:

在Oracle 12c中有新功能:DEFAULT ON NULL。例如:

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

因此,当您尝试在col2中INSERT null时,这将自动为7。

答案 1 :(得分:3)

正如本AskTom thread中所述,DEFAULT关键字仅作为列插入中的独立表达式使用,并且在与函数或表达式(如NVL)混合时不起作用。

换句话说,这是一个有效的查询:

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

如果变量为null,则可以对所有行使用动态查询,使用绑定变量或常量DEFAULT。这可以像使用:not_null_column_with_default_value中的字符串DEFAULT替换字符串$insert一样简单。

您还可以查看视图ALL_TAB_COLUMNS并使用nvl(:your_variable, :column_default)。默认值为列DATA_DEFAULT

答案 2 :(得分:1)

我认为最干净的方法是在INSERT语句中不提及它们。你可以开始编写触发器来填充默认值,但这对你所瞄准的目标来说是重要的。

是否有可能重新构建您的应用程序代码?在PHP中,您可以构造一个干净的INSERT语句而不会出现凌乱的情况,例如:像这样:

<?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);
?>

答案 3 :(得分:1)

性能更好的选择是第一个。

无论如何,据我所知,由于难以修改,您不希望重复插入列名称和值。您可以使用的另一个选项是运行带有returning子句的插入,然后执行更新:

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

似乎work with PHP

在此之后,您可以检查null绑定变量上的insered_value。如果为null,则可以运行以下更新:

UPDATE my_table
   SET not_null_column_with_default_value  = DEFAULT
 WHERE  pk_column = :pk_column: 

答案 4 :(得分:0)

  

我想使用一个插页   我想要的任何数据的声明   插入,不要费心检查是否   插入的值是否为空。

使用该列的默认值定义表。例如:

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

或更改现有表:

alter table myTable modify(created_date default sysdate);

现在你(或任何使用myTable的人)不必担心默认值。只知道对于这个例子,列仍然可以为空,所以有人可以显式插入null。如果不需要,也可以使列不为空。

编辑:假设已完成上述操作,您可以在insert语句中使用DEFAULT关键字。我会避免触发这个。