Вставить значение по умолчанию, когда вставлено значение NULL - PullRequest
11 голосов
/ 22 марта 2011

У меня есть база данных 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)
     ";        
}

Итак, я должен опустить столбецполностью, или у меня будет ошибка "попытка вставить ноль, а не нуль-столбец".Конечно, у меня есть несколько обнуляемых столбцов, поэтому оператор вставки кода очень нечитаем, уродлив, и мне просто не нравится этот способ.

Я хотел бы иметь одно утверждение, похожее на:

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?

РЕДАКТИРОВАТЬ :

Спасибо всем за ответы.Это говорит о том, что не существует «стандартного» способа достичь того, чего я хотел, поэтому я принял лучший ответ IMO: я должен перестать быть умным и придерживаться простого пропуска нулевых значений с помощью автоматически создаваемых операторов.

Не совсем то, что я хотел бы видеть, но нет лучшего выбора.

Ответы [ 5 ]

14 голосов
/ 06 мая 2016

Для тех, кто читает его сейчас:

В Oracle 12c появилась новая функция: ПО УМОЛЧАНИЮ НА НУЛЕ .Например:

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

Так что, когда вы попытаетесь вставить NULL в столбце col2, это автоматически будет 7.

3 голосов
/ 22 марта 2011

Как объяснено в этом потоке 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_value на строку DEFAULT в вашем $insert.

Вы также можете запросить представление ALL_TAB_COLUMNS и использовать nvl(:your_variable, :column_default).Значением по умолчанию является столбец DATA_DEFAULT.

1 голос
/ 23 марта 2011

Лучшим вариантом для производительности является первый.

В любом случае, как я понимаю, вы не хотите повторять имена и значения вставляемых столбцов из-за трудностей внесения изменений.Другой вариант, который вы можете использовать, - запустить вставку с , возвращающим предложение с последующим обновлением:

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 bind.Если оно пустое, вы можете запустить следующее обновление:

UPDATE my_table
   SET not_null_column_with_default_value  = DEFAULT
 WHERE  pk_column = :pk_column: 
1 голос
/ 22 марта 2011

Я думаю, что самый простой способ - не упоминать их в своем 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);
?>
0 голосов
/ 22 марта 2011

Я хотел бы использовать одну вставку заявление для любых данных, которые я хочу вставьте, и не беспокойтесь, чтобы проверить, если введенные значения являются нулевыми или нет.

Определите вашу таблицу со значением по умолчанию для этого столбца. Например:

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

или изменить существующую таблицу:

alter table myTable modify(created_date default sysdate);

Теперь вам (или любому, кто использует myTable) не нужно беспокоиться о значениях по умолчанию, как и должно быть. Просто знайте, что для этого примера столбец по-прежнему обнуляется, поэтому кто-то может явно вставить ноль. Если это нежелательно, также сделайте столбец не нулевым.

РЕДАКТИРОВАТЬ: Предполагая, что выше уже сделано, вы можете использовать ключевое слово DEFAULT в своем операторе вставки. Я бы избежал триггеров для этого.

...