创建一个接受插入值的 SQL 视图
Posted
技术标签:
【中文标题】创建一个接受插入值的 SQL 视图【英文标题】:Creating a SQL view that will accept inserted values 【发布时间】:2021-04-18 02:12:54 【问题描述】:我创建了一个 SQL 视图来检索我想要的结果集,但是当我尝试添加一组新值时它失败了。在网上搜索时,似乎 VIEW 有一些限制,并且可能不允许某些类型的连接,我尝试用几种不同的方式创建视图,但还没有成功,有没有人碰巧知道我可以使用的方法重写这个允许我在其中插入新值的创建视图查询?
观点:
CREATE VIEW NATIONAL_ITEMS
AS
SELECT item.itemno, item.itemdesc, item.itemprice
FROM item
FULL OUTER JOIN invoiceitem ON item.itemno = invoiceitem.itemno
WHERE item.itemdesc LIKE '%National%'
AND invoiceitem.invoiceno IS NULL
WITH CHECK OPTION;
我的插入语句不起作用:
INSERT INTO NATIONAL_ITEMS
VALUES ('123-456', 'National TV', 100);
我收到此错误:
从第 1 行开始的错误命令 - 插入 NATIONAL_ITEMS 值('123-456'、'National TV'、100) 命令行错误:1 列:1 错误报告 - SQL 错误:ORA-01733:此处不允许使用虚拟列 01733. 00000 - “此处不允许使用虚拟列”
任何帮助将不胜感激,谢谢。
【问题讨论】:
您可以简单地插入基表或在视图上创建一个INSTEAD OF
触发器,当您插入视图时,它会整理并为您执行此操作。
视图定义中使用的列之一是虚拟列吗?
您的视图与驾驶台没有 1:1 的关系。您不能对其进行 INSERT、UPDATE 或 DELETE。
您的查询没有多大意义。你正在做一个full outer join
,但是你在item.itemdesc
上有一个谓词,这使它有效地成为left outer join
。执行insert
后,您希望在invoiceitem
中显示哪些数据?
【参考方案1】:
为了在视图中插入视图,您有两个选项。
首先,您的视图必须包含您正在创建视图的表中存在的所有键,即不能有 DISTINCT
OR GROUP BY
子句。
如果您对表执行JOIN
同样适用于所有连接表,则表中的所有键都必须存在于视图中,并且不能有DISTINCT
OR GROUP BY
子句。
与视图中的行具有 1:1 行关系的表称为Key preserving table
其次,您可以在视图上创建而不是触发器。触发器将被触发,而不是 INSERT
、UPDATE
、OR DELETE
,并且在触发器中,您可以处理 DML 语句。
由于您的表没有保留密钥,因此您可以使用INSTEAD OF TRIGGER
。
CREATE OR REPLACE TRIGGER NATIONAL_ITEMS_TRG
INSTEAD OF INSERT
ON NATIONAL_ITEMS
FOR EACH ROW
BEGIN
INSERT INTO ITEM(itemno, itemdesc, itemprice) VALUES (:NEW.itemno, :NEW.itemdesc, :NEW.itemprice);
END;
【讨论】:
谢谢,这让我可以插入我需要的东西。只是好奇,我将如何使用您提到的“密钥保留”的另一种方法? 假设您创建了一个类似于 CREATE VIEW vw as SELECT department_id, SUM(salary) sum FROM EMPLOYEES;现在您想在此 VIEW 中插入一行,但数据不是表中存在的实际数据,并且视图被汇总并使用聚合函数具有派生列总和。但是如果你做一些简单的事情,比如 CREATE VIEW vw as SELECT employee_id, first_name, Salary FROM employee;因此表和视图具有 1:1 的行关系,很明显,您在视图中更新或插入或删除的任何行在表中都有相应的单行。没有歧义。 这并不意味着您不能使用谓词,它只是意味着您视图中的任何行都应该与表中的行具有 1:1 的关系。如果视图中有多个表,那么视图中的所有表也是如此,视图中的所有行必须具有 1:1 关系,并且可以通过添加连接表的键列来实现。以上是关于创建一个接受插入值的 SQL 视图的主要内容,如果未能解决你的问题,请参考以下文章