Fra*_*sca 2 sql-server ssms t-sql view
我有 2 个表,A 和 B,带有一个int主键和一个string名称。
我有一个第三个表 C,其中有 2 列将 A 和 B 的 ID 映射在一起。我想创建一个视图来编辑表 C 中的映射,但我希望视图显示Name值而不是IDs. 该视图将通过 SQL Server Management Studio 进行编辑。
例如,视图应该允许用户在项目列中输入“Item4”,在附件列中输入“Accessory1”,表 C 更新为新的行映射“4”到“1”。
我想知道是否可以将其设为可编辑视图,这样我就不必费心编写整个应用程序来管理它。
如果我转到 Microsoft SQL Server Management Studio 中的视图并右键单击,我可以编辑前 200 行。我知道此功能的限制是我只能在更改为单个表时进行编辑。我只会编辑一个表,所以可能有办法让它工作。有办法吗?(我的用户是熟悉 SQL Server 并且更喜欢直接访问他们的数据的人(交易员))。
CREATE TABLE dbo.Item
(
ItemID integer PRIMARY KEY,
ItemName varchar(50) NOT NULL UNIQUE
);
CREATE TABLE dbo.Accessory
(
AccessoryID integer PRIMARY KEY,
AccessoryName varchar(50) NOT NULL UNIQUE
);
CREATE TABLE dbo.ItemAccessory
(
ItemID integer REFERENCES dbo.Item (ItemID),
AccessoryID integer REFERENCES dbo.Accessory (AccessoryID),
PRIMARY KEY (ItemID, AccessoryID)
);
Run Code Online (Sandbox Code Playgroud)
INSERT dbo.Item
(ItemID, ItemName)
VALUES
(1, 'Item 1'),
(2, 'Item 2'),
(3, 'Item 3'),
(4, 'Item 4');
INSERT dbo.Accessory
(AccessoryID, AccessoryName)
VALUES
(1, 'Accessory 1'),
(2, 'Accessory 2'),
(3, 'Accessory 3'),
(4, 'Accessory 4');
INSERT dbo.ItemAccessory
(ItemID, AccessoryID)
VALUES
(1, 1),
(1, 2),
(2, 3),
(3, 4);
Run Code Online (Sandbox Code Playgroud)
CREATE VIEW dbo.ItemAccessoryName
WITH SCHEMABINDING
AS
SELECT
I.ItemName,
A.AccessoryName
FROM dbo.ItemAccessory AS IA
JOIN dbo.Accessory AS A
ON A.AccessoryID = IA.AccessoryID
JOIN dbo.Item AS I
ON I.ItemID = IA.ItemID;
Run Code Online (Sandbox Code Playgroud)
该视图不可直接更新:
INSERT dbo.ItemAccessoryName
(ItemName, AccessoryName)
VALUES
('Item 4', 'Accessory 4');
Run Code Online (Sandbox Code Playgroud)
消息 4405,级别 16,状态 1,第 61 行
视图或函数“dbo.ItemAccessoryName”不可更新,因为修改会影响多个基表。
我们可以使用代替触发器使任何视图可更新:
CREATE TRIGGER dbo_ItemAccessoryName_IOI
ON dbo.ItemAccessoryName
INSTEAD OF INSERT
AS
SET ROWCOUNT 0;
SET NOCOUNT ON;
INSERT dbo.ItemAccessory
(
ItemID,
AccessoryID
)
SELECT
I.ItemID,
A.AccessoryID
FROM Inserted AS INS
JOIN dbo.Item AS I
ON I.ItemName = INS.ItemName
JOIN dbo.Accessory AS A
ON A.AccessoryName = INS.AccessoryName;
Run Code Online (Sandbox Code Playgroud)
在尝试插入之前,触发器本质上将提供的名称转换为 ID。只要您具有良好的参照完整性,在触发器代码中进行额外检查的需求应该是最小的。例如,如果有人粘贴多个条目(例如,只有其中一些是有效的),则详细信息完全取决于您希望发生的情况。
如果您希望通过视图允许(一般)更新和删除,您将需要额外的触发器逻辑。例如:
DROP TRIGGER dbo.dbo_ItemAccessoryName_IOI;
GO
CREATE TRIGGER dbo_ItemAccessoryName_IOIUD
ON dbo.ItemAccessoryName
INSTEAD OF INSERT, UPDATE, DELETE
AS
SET ROWCOUNT 0;
SET NOCOUNT ON;
-- Handle deletions (including the delete part of an update)
DELETE IA
FROM dbo.ItemAccessory AS IA
JOIN dbo.Item AS I
ON I.ItemID = IA.ItemID
JOIN dbo.Accessory AS A
ON A.AccessoryID = IA.AccessoryID
JOIN Deleted AS DEL
ON DEL.ItemName = I.ItemName
AND DEL.AccessoryName = A.AccessoryName;
-- Handle inserts (including the insert part of an update)
INSERT dbo.ItemAccessory
(
ItemID,
AccessoryID
)
SELECT
I.ItemID,
A.AccessoryID
FROM Inserted AS INS
JOIN dbo.Item AS I
ON I.ItemName = INS.ItemName
JOIN dbo.Accessory AS A
ON A.AccessoryName = INS.AccessoryName;
Run Code Online (Sandbox Code Playgroud)