Как создать столбец not null в представлении
учитывая таблицу, как:
CREATE TABLE "MyTable"
(
"MyColumn" NUMBER NOT NULL
);
Я хочу создать вид типа:
CREATE VIEW "MyView" AS
SELECT
CAST("MyColumn" AS BINARY_DOUBLE) AS "MyColumn"
FROM "MyTable";
только где столбец "столбец mycolumn компонент компонент" "не нулевой".
в SQL Server это довольно прямолинейно:
CREATE VIEW [MyView] AS
SELECT
ISNULL(CAST([MyColumn] AS Float), 0.0) AS [MyColumn]
FROM [MyTable];
однако эквивалент Oracle приводит к столбцу "NULL":
CREATE VIEW "MyView" AS
SELECT
NVL(CAST("MyColumn" AS BINARY_DOUBLE), 0.0) AS "MyColumn"
FROM "MyTable";
есть ли в любом случае заставить Oracle пометить столбец представления как "не NULL" в метаданных?
2 ответов
вы не можете добавить в представление ограничение not null или check; см. этой и на той же странице "ограничения на не нулевые ограничения" и "ограничения на ограничения проверки". Вы можете добавить with check option
(против избыточного предложения where) для представления, но это не будет отмечено как not null
в словарь данных.
единственный способ, которым я могу думать, чтобы получить этот эффект, если вы находитесь на 11g, чтобы добавить значение приведения в качестве виртуального столбца в таблице и (если это все еще необходимо) создать мнение против этого:
ALTER TABLE "MyTable" ADD "MyBDColumn" AS
(CAST("MyColumn" AS BINARY_DOUBLE)) NOT NULL;
CREATE OR REPLACE VIEW "MyView" AS
SELECT
"MyBDColumn" AS "MyColumn"
FROM "MyTable";
desc "MyView"
Name Null? Type
----------------------------------------- -------- ----------------------------
MyColumn NOT NULL BINARY_DOUBLE
так как вы сказали в комментарии к dba.se, что это для издевательства над чем-то, вы можете использовать обычный столбец и триггер для имитации виртуального столбца:
CREATE TABLE "MyTable"
(
"MyColumn" NUMBER NOT NULL,
"MyBDColumn" BINARY_DOUBLE NOT NULL
);
CREATE TRIGGER "MyTrigger" before update or insert on "MyTable"
FOR EACH ROW
BEGIN
:new."MyBDColumn" := :new."MyColumn";
END;
/
CREATE VIEW "MyView" AS
SELECT
"MyBDColumn" AS "MyColumn"
FROM "MyTable";
INSERT INTO "MyTable" ("MyColumn") values (2);
SELECT * FROM "MyView";
MyColumn
----------
2.0E+000
и desc "MyView"
все-таки дает:
Name Null? Type
----------------------------------------- -------- ----------------------------
MyColumn NOT NULL BINARY_DOUBLE
как упоминал ли (также на dba.se), если вы хотите вставить/обновить представление, вы можете использовать instead of
триггер, с VC или поддельной версией.
Если вы может имеют ограничение NOT NULL для столбца представления я считаю, что выбор из представления затем завершится ошибкой, если столбец, о котором идет речь, равен NULL. Если это намерение, то следующее может дать вам то, что вы ищете:
CREATE OR REPLACE VIEW some_view AS
SELECT some_field,
some_other_field,
CASE
WHEN field_of_interest IS NOT NULL
THEN CAST(field_of_interest AS BINARY_DOUBLE)
ELSE 1 / 0
END AS field_of_interest_not_null
FROM some_table;
не очень привлекательно, и вы получаете уродливое сообщение "ORA-01476: деление равно нулю", если взята другая ветвь дела, но, возможно, это шаг на пути к "лучшему".
поделиться и наслаждаться.
EDIT: если цель состоит только в том, чтобы забрать строки, где ваш целевой столбец не равен нулю, возможно, вы могли бы добавить предложение WHERE в свое представление, как в:
CREATE OR REPLACE VIEW some_view AS
SELECT some_field,
some_other_field,
CAST(field_of_interest AS BINARY_DOUBLE) AS field_of_interest
FROM some_table
WHERE field_of_interest IS NOT NULL;
YMMV.
EDIT2: В Примере SQL Server показано, что функция ISNULL используется для обеспечения того, чтобы столбец никогда не был NULL. Если это приемлемо, вы можете сделать следующее:
CREATE OR REPLACE VIEW some_view AS
SELECT some_field,
some_other_field,
CAST(NVL(field_of_interest, 0.0) AS BINARY_DOUBLE) AS field_of_interest
FROM some_table
WHERE field_of_interest IS NOT NULL;
цитата Буллвинкля", на этот раз уверен, Фер!!!" :-)