我有一个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的最佳答案:我应该停止聪明并坚持通过自动构建的语句省略空值。
不完全是我想看到的,但没有更好的选择。
答案 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
在此之后,您可以检查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关键字。我会避免触发这个。