База данных 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
/