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

标签 sql sql-server sqlbulkcopy

我有两张 table 。以下只是这些表格的精简版本。

TableA
Id <pk> incrementing
Name varchar(50)

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

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

场景

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

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

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

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

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

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

最佳答案

SQLBulkCopy 使这个问题变得复杂,因此我会考虑使用临时表和 OUTPUT clause

示例,客户端伪代码和 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),并使用它来标识行批处理。

关于sql - 如何解决这个存储过程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3471152/

相关文章:

c# - 如何找到违规列?无法从字符串转换为 int32

php - 显示 mysql 表中每个类别的最后 2 个条目

sql-server - SSIS 派生列从字符串中删除文本,仅保留数值

.net - 在 SqlBulkCopy 之前截断

sql - 您可以使用 IS NOT NULL 和通配符作为搜索参数吗

sql-server - 如何优化 SQL Server 列存储对齐

database - 批量复制 - sybase

sql - 为什么多个OrderBy执行起来会消耗很多时间?

asp.net - 有没有任何工具可以查看针对数据库运行的查询?

php - 将命名参数与 PDO 一起用于 LIKE