在存储过程中插入或更新用户定义的表类型
Posted
技术标签:
【中文标题】在存储过程中插入或更新用户定义的表类型【英文标题】:Insert or Update user-defined table type in a stored procedure 【发布时间】:2014-03-28 09:15:02 【问题描述】:我目前正在从事一个项目,我经常将大量数据插入或更新到远程数据库。数据量约为 50 组数据,每组 500-800 行,进入同一张表。
目前我有一个存储过程,我调用它来插入或更新每一行(为了便于阅读而进行了简化):
ALTER PROCEDURE stat_memberstat_upsert
...
AS
BEGIN
UPDATE Memberstats ...
if(@@ROWCOUNT = 0)
BEGIN
INSERT INTO Memberstats ...
END
END
这可行,但正如您所见,它会挂载到对同一个存储过程的大量调用(最坏的情况是大约 100,000 次调用)。我正在研究用户定义的表类型,这听起来像是一个很好的解决方案,因为它减少了对数据库服务器的调用,并且结构更庞大。问题是,当我查看解决方案、教程和文档时,我发现没有人提到使用表类型执行插入/更新例程的方法;它是插入或更新。
在处理表类型时,有没有办法进行插入/更新调用?
另外,我考虑了两种解决方法:
1:使用光标
我可以使用游标遍历表类型值并为每一行调用上面的 stat_memberstat_upsert 过程。这不会阻止对过程的多次调用,但由于调用是从本地存储过程完成的,因此速度可能会提高。
How to do ForEach on user defined table type in SQL Server stored procedure?(回答“为什么不使用光标???”)
2:预验证数据
第二种解决方案是检索已经插入的行主键,根据传入数据验证它们并将它们分类到 2 个表中,其中一个用于插入,另一个用于更新。然后将两个表都执行到数据库中。这意味着我需要将其封装在事务中,以便在验证和执行插入和更新期间表不会更改。
这些都是一个好的解决方案吗?
【问题讨论】:
我不确定您在哪里查看过您只能插入或更新的印象,但您是否查看过MERGE
?
@Damien_The_Unbeliever 我从未听说过合并。谢谢你的提示;我目前正在检查是否可以使其与 Merge 一起使用
另外,可能超出了您的范围,但这听起来像是作为 SSIS 包更好地实现的东西?
@Damien_The_Unbeliever 你是救生员。 MERGE 适用于表类型,速度现在令人难以置信。谢谢!您能否创建一个答案,以便我们关闭它?
【参考方案1】:
这两种解决方案都可能进一步减慢速度。 您可以简单地将插入语句插入表中
ALTER PROCEDURE stat_memberstat_upsert
...
AS
INSERT INTO Memberstats_temp ...
END
并有一个批处理过程,该过程将在低流量时间运行,以在截断此临时表之后从 Memberstats_temp 表中更新/插入 Memberstats 表。如果您需要实时更新表格,这不是解决方案。
【讨论】:
以上是关于在存储过程中插入或更新用户定义的表类型的主要内容,如果未能解决你的问题,请参考以下文章
使用 JDBC 将用户定义的表类型传递给 SQL Server 存储过程