SQL 复制行并存储关系

huangapple go评论64阅读模式
英文:

SQL Replicate rows and store the relation

问题

使用一个在插入后触发的触发器,我想要在插入时复制行。
每插入一行到表中,应该复制指定次数。
行应该被复制的次数由应用程序的活动实例数量决定。
活动实例存储在另一个表中,原始表的每一行都有一个InstanceID列,引用与Instances表中的相关实例的关系。
原始和副本之间的关系应存储在另一个表中。

假设插入以下行:

ID Title InstanceID
1 Item1 1

并且Instances表如下所示:

ID Title
1 i1
2 i2
3 i3

交易结束后,表应如下所示:

ID Title InstanceID
1 Item1 1
2 Item1 2
3 Item1 3

存储这些关系的表将是:

OriginalID ReplicaID
1 2
1 3

我编写了一段查询来实现这一点,并且实际上已经复制了它。
但我遇到的问题是如何在新插入的ID旁边输出原始ID。
似乎我不能在OUTPUT子句中引用子查询,也找不到其他方法来实现。

这是我的查询的外观:

DECLARE @insertedIDs TABLE (ReplicaID INT, OriginalID INT)

INSERT INTO TABLE1 (InstanceID, Title,...)
OUTPUT inserted.ID INTO @insertedIDs
SELECT s.ID, p.Title, ... FROM inserted as p
-- 与活动实例交叉应用,以便我们每个活动实例都会复制一次
CROSS APPLY Instances_table s

--在这里,我希望存储映射,但是我无法获取@InsertedIDs表中的原始ID来执行此操作
INSERT INTO InstanceEntityMappings (OriginalID, ReplicaID) 
SELECT 'I_DONT_HAVE_IT', ID FROM @insertedIDs

我想知道是否有更好的方法来解决这个问题。

英文:

Using a after-insert trigger I want to replicate rows upon insertion.
Each row that gets inserted into to the table should be replicated a specified number of times.
The number of times the row should be replicated is determined by the number of active instances of an application.
Active instances are stored in another table and each row of the original table has a InstanceID column referencing the related Instance within Instances table.
The Relation between the original and replicas should be stored in another table.

Let's say the following row is inserted:

ID Title InstanceID
1 Item1 1

And the Instances table looks like below:

ID Title
1 i1
2 i2
3 i3

By the end of the transaction the table should be as:

ID Title InstanceID
1 Item1 1
2 Item1 2
3 Item1 3

And the table storing them relations would be:

OriginalID ReplicaID
1 2
1 3

I did write a piece of query to achieve this and got to the point of actually replicating it.
But what I struggle with is how to output the original id along with the newly inserted id.
It seems like I cannot reference subqueries inside OUTPUT clause and can't find any other way to do so.

This is how my query looks like:

DECLARE @insertedIDs TABLE (ReplicaID INT, OriginalID INT)

INSERT INTO TABLE1 (InstanceID, Title,...)
OUTPUT inserted.ID INTO @insertedIDs
SELECT s.ID, p.Title, ... FROM inserted as p
-- cross apply with active instances so that we will replicate once for every active
CROSS APPLY Instances_table s

--here I wish to store the mappings but i cannot get the original id inside the @InsertedIDs table to do so 
INSERT INTO InstanceEntityMappings (OriginalID, ReplicaID) 
SELECT 'I_DONT_HAVE_IT', ID FROM @insertedIDs

And I would love to know if there's a better approach in order to address this problem

答案1

得分: 1

我建议您在表上创建一个触发器来处理行复制。触发器将根据活动实例的数量复制行,并将映射存储在InstanceEntityMappings表中。

CREATE TRIGGER ReplicateRowsTrigger
ON TABLE1
AFTER INSERT
AS
BEGIN
    -- 根据活动实例插入复制的行
    INSERT INTO TABLE1 (InstanceID, Title, ...)
    SELECT i.InstanceID, p.Title, ...
    FROM inserted AS p
    CROSS JOIN Instances_table AS i
    WHERE i.ID IN (SELECT DISTINCT InstanceID FROM inserted)
        AND p.ID IN (SELECT ID FROM inserted);

    -- 将映射存储在InstanceEntityMappings表中
    INSERT INTO InstanceEntityMappings (OriginalID, ReplicaID)
    SELECT i.ID, t.ID
    FROM inserted AS i
    JOIN TABLE1 AS t ON i.InstanceID = t.InstanceID
    WHERE i.ID IN (SELECT ID FROM inserted);
END;
英文:

I would suggest you to create a trigger on the table to handle row replication. The trigger will replicate rows based on the number of active instances and store the mappings in the InstanceEntityMappings table.

CREATE TRIGGER ReplicateRowsTrigger
ON TABLE1
AFTER INSERT
AS
BEGIN
    -- Insert the replicated rows based on active instances
    INSERT INTO TABLE1 (InstanceID, Title, ...)
    SELECT i.InstanceID, p.Title, ...
    FROM inserted AS p
    CROSS JOIN Instances_table AS i
    WHERE i.ID IN (SELECT DISTINCT InstanceID FROM inserted)
        AND p.ID IN (SELECT ID FROM inserted);

    -- Store the mappings in the InstanceEntityMappings table
    INSERT INTO InstanceEntityMappings (OriginalID, ReplicaID)
    SELECT i.ID, t.ID
    FROM inserted AS i
    JOIN TABLE1 AS t ON i.InstanceID = t.InstanceID
    WHERE i.ID IN (SELECT ID FROM inserted);
END;

huangapple
  • 本文由 发表于 2023年6月22日 20:24:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76531873.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定