【发布时间】: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