给出如下表格:
CREATE TABLE "MyTable"
(
"MyColumn" NUMBER NOT NULL
);
我想创建一个类似的视图:
CREATE VIEW "MyView" AS
SELECT
CAST("MyColumn" AS BINARY_DOUBLE) AS "MyColumn"
FROM "MyTable";
仅在“MyColumn”列为“NOT NULL”的地方。
在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将视图的列标记为元数据中的“NOT NULL”?
答案 0 :(得分:6)
您不能向视图添加非null或检查约束;请参阅this并在同一页面上“对NOT NULL约束的限制”和“检查约束的限制”。您可以向视图添加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
正如Leigh所提到的(同样在dba.se上),如果您确实要插入/更新视图,可以使用instead of
触发器,使用VC或假版本。
答案 1 :(得分:1)
如果你 在视图列上有一个NOT NULL约束,我相信如果有问题的列是NULL,视图中的SELECT将会失败。如果这是意图,那么以下内容可能会为您提供所需内容:
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;
不是非常有吸引力,如果CASE的ELSE分支被采用,你会得到一个丑陋的“ORA-01476:除法等于零”消息,但也许这是迈向“更好”的道路上的一步。
分享并享受。
编辑:如果目标是仅选取目标列不为空的行,则可以在视图中添加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;
因人而异。
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;
引用Bullwinkle的话说,“这次确定!!!” : - )