Oracleデータベースと、null以外の列がいくつかあり、すべてデフォルト値のテーブルがあります。
挿入したいデータに対して1つの挿入ステートメントを使用したいので、挿入された値がnullであるかどうかをわざわざチェックする必要はありません。
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列をnullに挿入しようとしています」というエラーが発生します。もちろん、私は複数のnull許容列を持っているので、コードcreate insertステートメントは非常に読みにくく、醜く、そのようにそれが好きではありません。
次のようなステートメントが1つあります。
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) );
もちろん、これは架空のクエリです。 OracleDBMSでその目標を達成する方法を知っていますか?
[〜#〜]編集[〜#〜]:
ご回答ありがとうございます。私が望んでいたことを達成するための「標準的な」方法がないことを縫い合わせたので、IMOのベストアンサーを受け入れました。
正確には私が見たいものではありませんが、より良い選択はありません。
今それを読んでいる人のために:
Oracle 12cには、新機能があります: DEFAULT ON NULL 。例えば:
CREATE TABLE tab1 (
col1 NUMBER DEFAULT 5,
col2 NUMBER DEFAULT ON NULL 7,
description VARCHAR2(30)
);
したがって、col2にnullを挿入しようとすると、これは自動的に7になります。
この 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
_の文字列_$insert
_を文字列DEFAULT
に置き換えるのと同じくらい簡単です。
ビュー_ALL_TAB_COLUMNS
_をクエリして、nvl(:your_variable, :column_default)
を使用することもできます。デフォルト値は列_DATA_DEFAULT
_です。
パフォーマンスのためのより良いオプションは最初のものです。
とにかく、私が理解しているように、変更を加えるのは難しいので、挿入列の名前と値を繰り返したくありません。使用できるもう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
PHPで動作する のようです。
この後、insered_value
バインド変数でnull
を確認できます。 nullの場合は、次の更新を実行できます。
UPDATE my_table
SET not_null_column_with_default_value = DEFAULT
WHERE pk_column = :pk_column:
最もクリーンな方法は、INSERTステートメントでそれらについて言及しないことだと思います。デフォルト値を埋めるためにトリガーを書き始めることもできますが、それはあなたが目指しているものにとっては重装甲です。
アプリケーションコードを少し再構築することはできませんか? PHPでは、面倒なifを使用せずに、クリーンな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);
?>
挿入したいデータに対して1つの挿入ステートメントを使用したいので、挿入された値がnullであるかどうかをわざわざチェックする必要はありません。
その列のデフォルト値を使用してテーブルを定義します。例えば:
create table myTable
(
created_date date default sysdate,
...
)
tablespace...
または既存のテーブルを変更します。
alter table myTable modify(created_date default sysdate);
これで、あなた(またはmyTableを使用している人)は、デフォルト値について心配する必要がなくなりました。この例では、列はまだnull可能であるため、誰かが明示的にnullを挿入する可能性があることを知っておいてください。これが望ましくない場合は、列もnullにしないようにします。
編集:上記がすでに行われていると仮定すると、挿入ステートメントでDEFAULTキーワードを使用できます。私はこれの引き金を避けます。