12

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

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

插入空值时,有什么方法可以退回到默认列值?

我有这个代码:

<?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 插入非 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 的最佳答案:我应该停止聪明,坚持通过自动构建的语句省略空值。

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

4

5 回答 5

16

对于现在阅读它的人:

在 Oracle 12c 中有一个新特性:DEFAULT ON NULL。例如:

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

因此,当您尝试在 col2 中插入 null 时,它将自动为 7。

于 2016-05-06T10:42:57.997 回答
3

正如此AskTom 线程中所解释的,该DEFAULT关键字只能作为列插入中的独立表达式使用,并且在与 NVL 等函数或表达式混合时不起作用。

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

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

如果变量为空,您可以对所有行和绑定变量或常量 DEFAULT 使用动态查询。这可能就像:not_null_column_with_default_valueDEFAULT.$insert

您还可以查询视图ALL_TAB_COLUMNS并使用nvl(:your_variable, :column_default). 默认值为 column DATA_DEFAULT

于 2011-03-22T09:15:44.373 回答
1

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

是不是可以稍微重构你的应用程序代码?在 PHP 中,您可以构造一个干净的 INSERT 语句,而不需要凌乱的 if 语句,例如:

<?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);
?>
于 2011-03-22T09:17:11.710 回答
1

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

无论如何,据我了解,由于难以进行修改,您不想重复插入列名称和值。您可以使用的另一个选项是运行带有返回子句的插入,然后是更新:

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

它似乎适用于 PHP

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

UPDATE my_table
   SET not_null_column_with_default_value  = DEFAULT
 WHERE  pk_column = :pk_column: 
于 2011-03-22T21:55:51.017 回答
0

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

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

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

或更改现有表:

alter table myTable modify(created_date default sysdate);

现在您(或使用 myTable 的任何人)不必担心默认值,因为它应该是。只要知道对于这个例子,列仍然可以为空,所以有人可以显式地插入一个空值。如果不希望这样做,也使该列不为空。

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

于 2011-03-22T10:50:39.133 回答