【问题标题】:Multiple inserts using 'User Defined Table Type' (asp.net sql-server)使用“用户定义的表类型”(asp.net sql-server)进行多次插入
【发布时间】:2016-05-13 09:23:39
【问题描述】:

在我的 ASP.NET Web 应用程序中,我有一个 DataTable 填充了要插入 tblChildren 的数据。
将 DataTable 传递给 stored procedure
在 SP 中,我需要读取每一行(ei Loop 通过 DataTable),更改其中的几列(根据 tblParents 中的相关数据)并且只然后将该行插入 tblChildren。

SqlBulkCopy 不会这样做,我认为TVP 也不会这样做(不确定……还不太熟悉)。
当然,我可以遍历应用程序中的 DataTable 行并将每一行单独发送到 SP,但这意味着到 SqlServer 的往返行程有数百次。

我遇到了两种可能实现这一点的方法:(1) 临时表 (2) 光标。
第一个很乱,第二个,据我所知,不推荐)

任何指导将不胜感激。

编辑:
我尝试了用户自定义表格类型的方法。

因为我用 TT_Child_Family_Id 列中的值填充了表类型 (TT_Children)。
但是,在现实生活中,我不会知道这些值,我需要遍历 @my_TT_Children 并为每一行从 tblFamilies 获取值,如下所示:

SELECT Family_Id FROM tblFamilies WHERE Family_Name = TT_Child_Last_Name

(假设 tblFamilies.Family_Name 中始终存在 TT_Child_Last_Name 的等价物)

所以我的问题是 - 如何循环遍历表类型并为每一行查找不同表中的值?

编辑 2(解决方案):
在 Amir 的完美答案中,存储过程应该是这样的:

ALTER PROCEDURE [dbo].[usp_Z_Insert_Children]
@my_TT_Children TT_Children READONLY
AS
BEGIN
    INSERT INTO tblChildren(Child_FirstName,
                            Child_LastName,
                            Child_Family_ID)
        SELECT Cld.tt_child_FirstName,
               Cld.tt_child_LastNAme,
               Fml.Family_Id FROM @my_TT_Children Cld
                    INNER JOIN tblFamilies fml
                        ON Cld.TT_Child_LastName = Fml.Family_Name
END  

Amir 的注释:tblFamily 中的 Family_Name 列必须是唯一的,并且最好有索引。
(我还注意到,如果 TT_Child_LastName 在 tblFamilies 中没有匹配项,则不会插入该行,我永远不会知道它。这意味着我必须以某种方式检查所有行是否已成功处理)。

【问题讨论】:

  • 为什么不能使用最初用来填充 DataTable 的存储过程?
  • 我从 Excel 工作表中填充数据表。
  • 请解释一下“更改几列(根据 tblParents 中的相关数据)是什么意思……最好是创建一个 [Fiddle](www.sqlfiddle.com)。至少提供表结构以及您迄今为止尝试过的内容...

标签: asp.net sql-server stored-procedures inner-join sql-insert


【解决方案1】:

您可以将 tblFamilies 加入过程中的插入中,并从那里获取值。比循环更有效。 或者创建一个光标,一次做一个孩子。 1) 确保在 tblFamilies 中只出现一次 FamilyName。 2) 确保如果 tblFamilies 是一个大表,则 FamilyName 列被索引。

INSERT INTO tblChildren(Child_FirstName, Child_LastName, Child_Family_ID)
SELECT Cld.tt_child_FirstName,
Cld.tt_child_LastNAme,
Fml.FamilyID
FROM @my_TT_Children Cld
INNER JOIN tblFamilies fml on Cld.TT_Child_LastName = Fml.FamilyName

但请注意,如果 tblFamilies 每个 Family_Name 有多个条目,那么这将复制数据。在这种情况下,您需要在 where 中添加更多限制。

【讨论】:

  • 我知道,我知道...!我刚刚进入INNER JOINs 的世界,当你想出完美的答案时,我正在胡闹!非常感谢!我会将其标记为答案并使用您的解决方案编辑问题(其中有几个小字段名称拼写错误)。顺便说一句,tblFamilies 中的 Family_Name 是唯一的,当然也有索引。
猜你喜欢
  • 2018-02-27
  • 1970-01-01
  • 2012-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-29
  • 1970-01-01
相关资源
最近更新 更多