我在创建触发器时遇到问题。数据库模型如下所示:
CREATE TABLE Unit (
SerialNO VARCHAR(3)
PRIMARY KEY (serialNO)
);
CREATE TABLE PackageConfig (
PartNO VARCHAR(15),
SomeValue VARCHAR(20),
PRIMARY KEY (PartNO)
);
CREATE TABLE Package (
ID INT IDENTITY(1,1),
Config VARCHAR(15),
PRIMARY KEY (ID),
FOREIGN KEY (Config) REFERENCES PackageConfig(PartNO)
);
CREATE TABLE UnitInPackage (
Package INT,
Unit VARCHAR(3),
PRIMARY KEY (Package,Unit),
FOREIGN KEY (Package) REFERENCES Package(ID),
FOREIGN KEY (Unit) REFERENCES Unit(SerialNO)
);
有Units
,PackageConfigurations
和Packages
。一个包只有一个PackageConfiguration
,Package
和Unit
之间的关系是多(单位)到最多一个(包)。
我想要完成的是一个视图触发器,让我可以执行以下操作(假设PackageConfig
和Units
存在):
INSERT INTO v_MultiUnitPackage (PackageConfig, Unit1, Unit2, Unit3)
VALUES ('SomeConfig','abc','bcd','cde');
触发器内部会执行以下操作:
DECLARE @last INT;
INSERT INTO Package (Config) VALUES ('SomeConfig');
SET @last = SCOPE_IDENTITY();
INSERT INTO UnitInPackage (Package,Unit)
VALUES (@last,'abc'),(@last,'bcd'),(@last,'cde');
或者更多列:
INSERT INTO Package (Config) VALUES ('SomeConfig');
SET @last = SCOPE_IDENTITY();
INSERT INTO UnitInPackage (Package,Unit)
VALUES (@last,'hgf'),(@last,'gfe'),(@last,'fed'),(@last,'edc'),(@last,'dcb'),(@last,'cba');
总结一下,我想创建一个触发器,它接受PackageConfig
和N个Units
并将它们插入相应的表中。
我一直在研究创建一个虚拟视图,它只具有正确的数据类型和足够数量的列,以允许我想要的单位数但却找不到解决方案。
我还查看了Package.ID
分组的内容,并为每个组选择了尚未选择到前一列的第一个单元。由于GROUP BY
仅适用于聚合函数,因此我不确定如何实现这一想法。
实际上我认为不需要超过5个左右的单位,但更喜欢我的问题的通用解决方案。
也许有一个非常简单的解决方案,我只是没有看到。非常感谢任何帮助。
答案 0 :(得分:1)
使用视图插入是一种方法,因此您只需要使用所需的单位数量更新虚拟视图。以下是触发器的外观:
create view v_MultiUnitPackage
as
select 'Some-Config' as PackageConfig, 'abc' as Unit1, 'bcd' as Unit2, 'cde' as Unit3
go
create TRIGGER tg_I_v_MultiUnitPackage
ON v_MultiUnitPackage
INSTEAD OF INSERT
AS
BEGIN
DECLARE @last INT;
INSERT INTO Package (Config)
SELECT inserted.PackageConfig
FROM inserted
SET @last = SCOPE_IDENTITY();
INSERT INTO UnitInPackage (Package,Unit)
SELECT @last, inserted.Unit1
FROM inserted;
INSERT INTO UnitInPackage (Package,Unit)
SELECT @last, inserted.Unit2
FROM inserted;
INSERT INTO UnitInPackage (Package,Unit)
SELECT @last, inserted.Unit3
FROM inserted;
END
在我看来,更好的选择是将单元作为XML传递给存储过程并在那里处理插入。以下是程序的外观:
CREATE PROCEDURE usp_i_PackageUnits
(
@PackageConfig varchar(15),
@Units xml -- <root><unit>abc</unit><unit>bcd</unit><unit>cde</unit>
)
AS
BEGIN
DECLARE @last INT;
INSERT INTO Package (Config) VALUES (@PackageConfig);
SET @last = SCOPE_IDENTITY();
INSERT INTO UnitInPackage (Package,Unit)
select node.value('(.)[1]', 'VARCHAR(3)') from @xml.nodes('/root/unit')as result(node)
END