База данных ORACLE: VIEW имеет обнуляемый столбец после объединения двух таблиц с необнуляемым столбцом

В базе данных Oracle:

Мне нужно, чтобы PRODUCT_ID столбец в поле зрения не будет обнуляемым. Вид UNION из двух таблиц, что в каждой на столбце PRODUCT_ID не обнуляется. Но по какой-то причине в этом столбце нет нуля.

синтаксис:

SELECT MAP_DATA.PRODUCT_ID, MAP_DATA.PRODUCT NAME
FROM (
    select PRODUCT_ID , PRODUCT_NAME
    FROM TABLE_1

    UNION 

    SELECT PRODUCT_ID , PRODUCT_NAME
    FROM TABLE_2
      ) MAP_DATA

Спасибо за помощников

1 ответ

Проблема в том, что ваше представление не является обновляемым. Это только для чтения, потому что основной запрос представляет собой объединение двух таблиц.

Если бы у вас был такой вид

create or replace view view_2
    (PRODUCT_ID
    , PRODUCT_NAME)
as
SELECT MAP_DATA.PRODUCT_ID, MAP_DATA.PRODUCT_NAME
FROM  TABLE_2 MAP_DATA
with check option
/

Затем запрос на all_tab_cols за 'VIEW_2' показал бы nullable='N', Это связано с тем, что Oracle может напрямую сопоставлять столбцы в представлении со столбцами в базовой таблице. Это невозможно сделать с помощью запроса UNION (поскольку вполне допустимо, чтобы столбцы одной таблицы обнулялись, а другая - обязательны).

В простом представлении мы можем выполнить оператор вставки непосредственно против представления. Но мы не можем сделать это с таким представлением, как ваше, по понятным причинам (в какую таблицу должна войти новая запись?). Чтобы сделать представление обновляемым, нам нужно написать триггер INSTEAD OF, в котором мы можем применять любые необходимые нам бизнес-правила.

Oracle позволяет нам определять первичный ключ и уникальные ограничения для представлений (используя магию RELY DISABLE NOVALIDATE условие), но не ограничения NOT NULL (т. е. проверка).

Обратите внимание, что столбец остается обнуляемым, даже если мы определяем представление с помощью первичного ключа:

create or replace view view_1
(PRODUCT_ID
, PRODUCT_NAME
, constraint v1_pk primary key (product_id) rely disable novalidate
)
as
SELECT MAP_DATA.PRODUCT_ID
       , MAP_DATA.PRODUCT_NAME

FROM (
    select PRODUCT_ID , PRODUCT_NAME
    FROM TABLE_1

    UNION 

    SELECT PRODUCT_ID , PRODUCT_NAME
    FROM TABLE_2
      ) MAP_DATA
 with check option
/
Другие вопросы по тегам