如何解决这个存储过程问题

发布于 2024-09-14 10:39:06 字数 696 浏览 2 评论 0原文

我有2张桌子。以下只是这些表格的精简版本。

TableA
Id <pk> incrementing
Name varchar(50)

TableB
TableAId <pk> non incrementing
Name varchar(50)

现在这些表彼此之间存在关系。

场景

用户 1 访问我的网站并执行一些操作(在本例中向表 A 添加行)。因此,我使用 SqlBulkCopy 表 A 中的所有数据。

但是,我还需要将数据添加到表 B 中,但我不知道表 A 中新创建的 Id,因为 SQLBulkCopy 不会返回这些数据。

所以我正在考虑有一个存储过程来查找表 B 中不存在的所有 id,然后将它们插入。

INSERT INTO TableB (TableAId , Name)
SELECT Id,Name FROM TableA as tableA
WHERE not exists( ...)

但这会带来一个问题。用户随时可以从 TableB 中删除某些内容,因此,如果用户删除了一行,然后另一个用户出现,甚至同一用户出现并对表 A 执行某些操作,我的存储过程将带回表 B 中已删除的行。因为它仍然存在于表 A 中,但不存在于表 B 中,因此满足存储过程条件。

那么有没有更好的方法来处理使用批量插入时需要更新的两个表呢?

I have 2 tables. The following are just a stripped down version of these tables.

TableA
Id <pk> incrementing
Name varchar(50)

TableB
TableAId <pk> non incrementing
Name varchar(50)

Now these tables have a relationship to each other.

Scenario

User 1 comes to my site and does some actions(in this case adds rows to Table A). So I use a SqlBulkCopy all this data in Table A.

However I need to add the data also to Table B but I don't know the newly created Id's from Table A as SQLBulkCopy won't return these.

So I am thinking of having a stored procedure that finds all the id's that don't exist in Table B and then insert them in.

INSERT INTO TableB (TableAId , Name)
SELECT Id,Name FROM TableA as tableA
WHERE not exists( ...)

However this comes with a problem. A user at any time can delete something from TableB so if a user deletes say a row and then another user comes around or even the same user comes around and does something to Table A my stored procedure will bring back that deleted row in Table B. Since it will still exist in Table A but not Table B and thus satisfy the stored procedure condition.

So is there a better way of dealing with two tables that need to be updated when using bulk insert?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

静谧幽蓝 2024-09-21 10:39:06

SQLBulkCopy 使这变得复杂,因此我考虑使用临时表和 OUTPUT 子句

示例,在客户端伪代码和 SQL 混合中

create SQLConnection

Create #temptable
Bulkcopy to #temptable

Call proc on same SQLConnection

proc:
   INSERT tableA (..)
   OUTPUT INSERTED.key, .. INTO TableB
   SELECT .. FROM #temptable

close connection

注意:

  • temptable 将位于连接本地并被隔离

  • 对 A 和 B 的写入将是原子
  • 重叠的,或者稍后的写入不关心 A 和 B 稍后会发生什么,
  • 强调最后一点,A 和 B 只会从#temptable 中的行集

替代方案:

向 A 和 B 添加另一列(称为 sessionid),并使用它来标识行批次。

SQLBulkCopy complicates this so I'd consider using a staging table and an OUTPUT clause

Example, in a mixture of client pseudo code and SQL

create SQLConnection

Create #temptable
Bulkcopy to #temptable

Call proc on same SQLConnection

proc:
   INSERT tableA (..)
   OUTPUT INSERTED.key, .. INTO TableB
   SELECT .. FROM #temptable

close connection

Notes:

  • temptable will be local to the connection and be isolated

  • the writes to A and B will be atomic
  • overlapping or later writes don't care about what happens later to A and B
  • emphasising the last point, A and B will only ever be populated from the set of rows in #temptable

Alternative:

Add another column to A and B called sessionid and use that to identify row batches.

给不了的爱 2024-09-21 10:39:06

一种选择是使用 SQL Server 输出子句:

INSERT YourTable (name)
OUTPUT INSERTED.*
VALUES ('NewName')

这会将插入行的 id, name 返回给客户端,以便您可以在第二个表的插入操作中使用它们。

One option would be to use SQL Servers output clause:

INSERT YourTable (name)
OUTPUT INSERTED.*
VALUES ('NewName')

This will return the id, name of the inserted rows to the client, so you can use them in the insert operation for the second table.

林空鹿饮溪 2024-09-21 10:39:06

作为替代解决方案,您可以使用数据库触发器 更新第二个表。

Just as an alternative solution you could use database triggers to update the second table.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文