我们正从sql server端迁移到oracle。
在sqlserver上我们曾经有过如下的视图
create view blah
AS
Select column1,
column2
FROM blah;
但在oracle上执行此操作会产生循环视图错误。
这是不允许在甲骨文那边?
答案 0 :(得分:5)
您无法拥有视图引用。它在逻辑上没有意义。视图本质上是一个缓存查询,其结果显示为表。查询如何引用自身?
实际上,Oracle中不允许使用循环视图定义。如果您有循环视图定义,那么您的数据库代码中可能存在应该解决的错误。也许从SQL服务器到Oracle的转换是有缺陷的,并且意外地引入了这个循环定义?
答案 1 :(得分:2)
您实际上可以在ORACLE中执行此操作,但它更脆弱,因为您需要明确列出CTE的输出列。因此,如果更改表格,则需要手动更新CTE。
以下是我们的数据库中的一个示例,显示了如何计算记录的层次深度...
CREATE OR REPLACE VIEW deploy.PHARMACYDISPENSE_EX
AS
WITH SRC (
PDID, WAREID, GCN_SEQNO, QTY, UOFM, XACTDTTM, CREATEDON, PROCESSEDON,
XACTTYPE, OPDID, CLOSEDON, BYPASSEDON, BYPASSEDBY, ITEMNO, LOTNO,
EXP_DATE, VOLUMETYPE, POTYPE, DEPTH
) AS (
SELECT D.PDID, D.WAREID, D.GCN_SEQNO, D.QTY, D.UOFM, D.XACTDTTM,
D.CREATEDON, D.PROCESSEDON, D.XACTTYPE, D.OPDID, D.CLOSEDON,
D.BYPASSEDON, D.BYPASSEDBY, D.ITEMNO, D.LOTNO, D.EXP_DATE,
D.VOLUMETYPE, D.POTYPE, 0 FROM deploy.PHARMACYDISPENSE D
WHERE OPDID IS NULL
UNION ALL
SELECT D.PDID, D.WAREID, D.GCN_SEQNO, D.QTY, D.UOFM, D.XACTDTTM,
D.CREATEDON, D.PROCESSEDON, D.XACTTYPE, D.OPDID, D.CLOSEDON,
D.BYPASSEDON, D.BYPASSEDBY, D.ITEMNO, D.LOTNO, D.EXP_DATE,
D.VOLUMETYPE, D.POTYPE, (S.DEPTH + 1)
FROM deploy.PHARMACYDISPENSE D JOIN SRC S ON S.PDID = D.OPDID
)
SELECT PD.*
FROM SRC PD;
这里的重要部分是WITH SRC (<output column list>) AS ...
。您需要输出列列表。所以它有可能,并且确实有效,它只需要比SQL Server中更多的代码。
答案 2 :(得分:0)
你的例子不完整 - 至少没有显示相关部分。:
-- create a table
CREATE TABLE Scrap
(fieldName VARCHAR2(20));
-- create a view
CREATE VIEW ScrapVW1
AS
SELECT * FROM Scrap;
-- create a second view that uses the first view
CREATE VIEW ScrapVW2
AS
SELECT * FROM Scrap
UNION ALL
SELECT * FROM ScrapVW1;
-- recreate the first view that references the 2nd view which contains a reference to itself
CREATE OR REPLACE VIEW SCRAP_VW1
AS
SELECT * FROM ScrapVW2;
尝试重新创建ScrapVW1时出现循环引用错误。我猜你的转换中会发生一些无意的名称冲突。如果它非常复杂,我将摆脱'CREATE OR REPLACE VIEW'语法,只需使用CREATE VIEW,然后会给你'ORA-00955名称已经使用'错误。
答案 3 :(得分:0)
Oracle处理的分层问题显然不同于SQL。您可以使用clause
来连接,而不是使用自我参照视图 SELECT employee_id, last_name, manager_id
FROM employees
CONNECT BY PRIOR employee_id = manager_id;