As an example:
create table dbo.tOrders ( OrderID int not null identity primary key, CustomerID int not null ); create table dbo.tOrderPos ( OrderID int not null foreign key references dbo.tOrders, OrderPosNo int null, ProductID int null ); create clustered index ciOrderPos on dbo.tOrderPos (OrderID, OrderPosNo); go create trigger dbo.trInsertOrderPos on dbo.tOrderPos for insert as begin update opo set OrderPosNo = isnull(opo2.MaxOrderPosNo,0) + opo.RowNo from (select OrderID, OrderPosNo, RowNo = row_number() over (partition by OrderID order by (select 1)) from dbo.tOrderPos opo where OrderPosNo is null) opo cross apply (select MaxOrderPosNo = max(opo2.OrderPosNo) from dbo.tOrderPos opo2 where opo2.OrderID = opo.OrderID) opo2 where exists (select * from inserted i where i.OrderID = opo.OrderID); end; go declare @OrderID1 int; declare @OrderID2 int; insert into dbo.tOrders (CustomerID) values (11); set @OrderID1 = scope_identity(); insert into dbo.tOrderPos (OrderID, ProductID) values (@OrderID1, 1), (@OrderID1, 2), (@OrderID1, 3); insert into dbo.tOrders (CustomerID) values (12); set @OrderID2 = scope_identity(); insert into dbo.tOrderPos (OrderID, ProductID) values (@OrderID2, 4), (@OrderID2, 5); insert into dbo.tOrderPos (OrderID, ProductID) values (@OrderID1, 6); select * from dbo.tOrderPos; go drop trigger dbo.trInsertOrderPos; drop table dbo.tOrderPos; drop table dbo.tOrders; go
The difficulty was to allow multiple inserts and delayed inserts. NTN
Another option is to use instead of the trigger:
create trigger dbo.trInsertOrderPos on dbo.tOrderPos instead of insert as begin insert into dbo.tOrderPos (OrderID, OrderPosNo, ProductID) select OrderID, OrderPosNo = isnull( (select max(opo.OrderPosNo) from dbo.tOrderPos opo where opo.OrderID = i.OrderID), 0) + row_number() over (partition by OrderID order by (select 1)), ProductID from inserted i; end;
Unfortunately, it seems that it is not possible to set OrderPosNo "not null", because several insertion elements will lead to duplicate keys. Therefore, I could not use the primary key and instead used a clustered index.
source share