1

私はいくつかの関連トピックを見てきましたが、私の質問は完全には答えられていません:

Web アプリケーションのコード ビハインドでストアド プロシージャを実行する場合、次のようなセットアップがあります。問題は、複数の製品を挿入する可能性に直面していることです。何度も実行するExecuteNonQueryのではなく、すべてを 1 つにまとめて実行したいと考えています。foreach loopn

これを行う方法がわかりません。現在のセットアップで可能かどうかもわかりません。

コードは自明である必要がありますが、明確化が必要な場合はお知らせください。ありがとう。

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

すべてのデータをテーブル値パラメーターとして渡すことができます-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

ループの外側でコマンドの 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

物事を行う純粋な方法からは理想的ではありませんが、フレームワークやライブラリによって制限される場合があり、特定の方法でストアド プロシージャを呼び出し、特定の方法でパラメーターをバインドし、接続が一部としてプールによって管理されることを余儀なくされます。あなたのフレームワークの。

このような状況で機能することがわかっている方法は、多くのパラメーターを使用してストアド プロシージャを単純に記述することです。通常は、名前の後に番号を付けます。 、おそらく 32 と言います。

このための行を生成するために、何らかの形式のスクリプト言語を使用できます。

ストアド プロシージャを取得して、null を許可するテーブル パラメータに最初にすべての値を挿入し、次に Johnv2020 の回答と同様の方法で、このデータに対して一括挿入/マージを行うことができます。最初に null 行を削除できます。

通常、一度に 1 つずつ実行するよりも効率的です (一部はデータベース操作自体のため、一部は接続を取得してプロシージャを呼び出す際のフレームワークのオーバーヘッドのためなど)。

于 2019-04-09T11:52:49.397 に答える