1

我查看了一些相关主题,但我的问题没有得到完全回答:

在我的 Web 应用程序的代码中运行我的存储过程时,我有以下类型的设置。问题是我现在面临插入多个产品的可能性,我想一次性完成所有操作,ExecuteNonQuery而不是做一个foreach loop并运行n多次。

我不确定如何使用我当前的设置来执行此操作,或者是否可以。

代码应该有点自我解释,但如果需要澄清,请告诉我。谢谢。

SqlDatabase database = new SqlDatabase(transMangr.ConnectionString);
DbCommand commandWrapper = StoredProcedureProvider.GetCommandWrapper(database, "proc_name", useStoredProc);

database.AddInParameter(commandWrapper, "@ProductID", DbType.Int32, entity._productID);
database.AddInParameter(commandWrapper, "@ProductDesc", DbType.String, entity._desc);
...more parameters...


Utility.ExecuteNonQuery(transMangr, commandWrapper);

过程

ALTER PROCEDURE [dbo].[Products_Insert]
-- Add the parameters for the stored procedure here
         @ProductID int,
         @Link      varchar(max)
         @ProductDesc          varchar(max)
         @Date          DateTime
    AS BEGIN

SET NOCOUNT ON;


INSERT INTO [dbo].[Prodcuts]
    ( 
        [CategoryID],
        [Link],
        [Desc],
        [Date]
    )
VALUES
    (
        @ProductID,
        @Link,
        @ProductDesc,
        @Date
    )

结尾

4

4 回答 4

1

您应该可以在循环中运行您的存储过程。只要确保你很少提交,而不是在每次插入之后。

对于替代方案,您已经找到了有关加载数据的讨论。

就个人而言,我喜欢这种形式的 SQL 批量插入,insert into myTable (select *, literalValue from someOtherTable); 但在你的情况下可能不会这样做。

于 2013-06-17T19:07:49.143 回答
0

为循环外的命令定义 commandWrapper 和参数,然后在循环中,您只需分配参数值并执行 proc。

SqlDatabase database = new SqlDatabase(transMangr.ConnectionString);
DbCommand commandWrapper = StoredProcedureProvider.GetCommandWrapper(database, "proc_name", useStoredProc);

database.AddInParameter(commandWrapper, "@ProductID", DbType.Int32 );
database.AddInParameter(commandWrapper, "@ProductDesc", DbType.String);
...more parameters...

foreach (var entity in entitties)
{
    database.SetParameterValue(commandWrapper, "@ProductID",entity._productID);
    database.SetParameterValue(commandWrapper, "@ProductDesc",entity._desc);
    //..more parameters...
    Utility.ExecuteNonQuery(transMangr, commandWrapper);
}
于 2013-06-17T20:55:41.557 回答
0

您可以将所有数据作为表值参数传递 - MSDN 在这里有一篇很好的文章

类似于以下内容的东西应该可以工作

CREATE TABLE dbo.tSegments (

SegmentID BIGINT NOT NULL CONSTRAINT pkSegment PRIMARY KEY CLUSTERED,
SegCount BIGINT NOT NULL

);

CREATE TYPE dbo.SegmentTableType AS TABLE ( SegmentID BIGINT NOT NULL );

CREATE PROCEDURE dbo.sp_addSegments

  @Segments dbo.SegmentTableType READONLY

AS

BEGIN MERGE INTO dbo.tSegments AS tSeg

USING @Segments AS S
ON tSeg.SegmentID = S.SegmentID
WHEN MATCHED THEN UPDATE SET T.SegCount = T.SegCount + 1
WHEN NOT MATCHED THEN INSERT VALUES(tSeg.SegmentID, 1);

结尾

于 2013-06-17T19:22:47.237 回答
0

从纯粹的做事方式来看并不理想,但有时会受到框架和库的限制,并且您被迫以某种方式调用存储过程,以某种方式绑定参数,并且连接由池作为一部分管理你的框架。

在这种情况下,我们发现一种可行的方法是简单地编写带有大量参数的存储过程,通常是一个名称后跟一个数字,例如@ProductId1、@ProductDesc1、@ProductId2、@ProductDesc2,直到您决定的数字,可能说 32。

您可以使用某种形式的脚本语言来为此生成行。

您可以让存储过程首先将所有值插入到允许空值的表参数中,然后以类似于 Johnv2020 的答案的方式对此数据进行批量插入/合并。您可以先删除空行。

它通常比一次做一个更有效(部分原因是数据库操作本身,部分原因是您的框架在获取连接以调用过程等方面的开销)

于 2019-04-09T11:52:49.397 回答