0

ストアド プロシージャに渡す前に、すべてのパラメーターに @ のプレフィックスが付けられます。つまり、foreach ループの領域外で、2 回目の反復から、ストアド プロシージャが呼び出されると、すべてのパラメーター名の前に @ が付けられ、2 回目の反復から例外メッセージが取得されます。

{"プロシージャまたは関数 UspUpdateProctorSignalByScheduleUserID に指定された引数が多すぎます。"}

以下に示すスニペットの部分的なコードを次に示します。

[WebMethod]
public static List<OnlineProctor> UpdateAllProctorStatus(ProctoringScheduledUserInfoList scheduledUsersList)
{
    #region Outside of foreach loop parameter's name will be prefixed to @ from the second iteration of the loop
        List<object> parameters = new List<object>();

        parameters.Add(SqlHelper.BuildSqlParameter("Status", SqlDbType.VarChar, 10, "status", null, ParameterDirection.Output));

        if (proctorStatus == "PAUSE")
            parameters.Add(SqlHelper.BuildSqlParameter("ScheduleExtensionTime", SqlDbType.Int, sizeof(Int16), "ScheduleExtensionTime", scheduledUsersList.PauseTime));

        parameters.Add(SqlHelper.BuildSqlParameter("ProctorSignal", SqlDbType.TinyInt, sizeof(Int16), "ProctorSignal", scheduledUsersList.ProctorSignal));

    #endregion

    foreach (Int64 scheduleUserID in scheduledUsersList.ScheduleUserID)
    {
        parameters.Add(SqlHelper.BuildSqlParameter("ScheduleDetailUserID", SqlDbType.BigInt, sizeof(Int64), "ScheduleDetailUserID", scheduleUserID));

        proctoringUserListDT = SqlHelper.ExecuteDataTable(CommandType.StoredProcedure, "UspUpdateProctorSignalByScheduleUserID", parameters.ToArray(), false);

        if (proctorStatus == "PAUSE")
            parameters.RemoveAt(3);
        else
            parameters.RemoveAt(2);
    }

}

実結果:

を。I 反復の場合

parameters | Count = 4
[0] {Status}
            Value   null

[1] {ScheduleExtensionTime}
            Value   0

[2] {ProctorSignal}
            Value   1

[3] {ScheduleDetailUserID}
        Value  943417

declare @p1 varchar(10)
set @p1='S001'
exec UspUpdateProctorSignalByScheduleUserID @Status=@p1 output,@ScheduleExtensionTime=0,@ProctorSignal=1,@ScheduleDetailUserID=943417
select @p1

b. II 反復の場合

parameters | Count = 4
[0] {@Status}
        Value   "S001"

[1] {@ScheduleExtensionTime}
        Value   0

[2] {@ProctorSignal}
        Value   1

[3] {ScheduleDetailUserID}
        Value  943419


declare @p1 varchar(10)
set @p1=NULL
exec UspUpdateProctorSignalByScheduleUserID @@Status=@p1 output,@@ScheduleExtensionTime=0,@@ProctorSignal=1,@ScheduleDetailUserID=943419
select @p1

期待される結果:

b. II 反復の場合

parameters | Count = 4
[0] {Status}
        Value   null

[1] {ScheduleExtensionTime}
        Value   0

[2] {ProctorSignal}
        Value   1

[3] {ScheduleDetailUserID}
        Value  943419


declare @p1 varchar(10)
set @p1='S001'
exec UspUpdateProctorSignalByScheduleUserID @Status=@p1 output,@ScheduleExtensionTime=0,@ProctorSignal=1,@ScheduleDetailUserID=943419
select @p1

ここで、プロパティは 2 回目の反復以降に変更されます

> ParameterName = "@Status" 
> ParameterNameFixed = "@Status"
> _parameterName = "@Status"

foreach ループ内で宣言および初期化すると、同じスニペットが完全に機能します。

しかし、foreach ループ内では、特定のインデックス 3 のリストif (proctorStatus == "PAUSE")を削除するかどうかを条件がチェックします。parameters.RemoveAt(3);

LINQorLambda演算子を使用して、つまり、ScheduleDetailUserIDループの各反復内で特定のオブジェクトを削除することによって、同じ条件を記述できますか?


SP で更新:

ALTER PROC [dbo].[UspUpdateProctorSignalByScheduleUserID]
(
  @ScheduleDetailUserID BIGINT,
  @ProctorSignal TINYINT,
  @Status VARCHAR(5)='' OUTPUT,
  @ScheduleExtensionTime INT=0
)
--WITH ENCRYPTION     
AS
BEGIN
SET NOCOUNT ON;
    BEGIN TRY 
        /*  ---#8*/
        DECLARE @UserTestStatus TINYINT

        SELECT @UserTestStatus = [Status]  
        FROM ScheduleUserDetail 
        WHERE ScheduleDetailUserID = @ScheduleDetailUserID

        IF @UserTestStatus = 2 --#14
        BEGIN
            SET @Status='S004'
            RETURN
        END --#14

        IF @UserTestStatus < 2  --#9
            BEGIN
                IF @ProctorSignal=2
                    BEGIN
                        UPDATE ScheduleUserDetail SET ProctorSignal=@ProctorSignal,ScheduleExtensionTime=(CASE WHEN ISNULL(@ScheduleExtensionTime,0)>0 THEN @ScheduleExtensionTime END), --#7
                        [Status]=@ProctorSignal
                        WHERE ScheduleDetailUserID=@ScheduleDetailUserID
                        SET @Status='S001'--Updated SuccessFully
                        SET @UserTestStatus = @ProctorSignal
                    END
                ELSE
                    BEGIN
                        UPDATE ScheduleUserDetail SET ProctorSignal=@ProctorSignal,ScheduleExtensionTime=(CASE WHEN ISNULL(@ScheduleExtensionTime,0)>0 THEN @ScheduleExtensionTime END) --#7
                        WHERE ScheduleDetailUserID=@ScheduleDetailUserID
                        SET @Status='S001'--Updated SuccessFully
                    END
            END

        IF @Status='S001'
            BEGIN
                SELECT LoginName AS StudentName,@ProctorSignal AS ProctorSignal,
                (
                    CASE    WHEN @UserTestStatus = 2 AND @ProctorSignal=2 THEN 5 --Suspended #14
                            WHEN @UserTestStatus = 1 AND @ProctorSignal=1 THEN 6 --Paused #14
                            ELSE SUD.[Status]
                    END
                ) AS TestStatus  --#10  --#11
                FROM [User] U
                INNER JOIN ScheduleUser SU ON SU.UserID=U.UserID
                INNER JOIN ScheduleUserDetail SUD ON SUD.ScheduleDetailUserID=SU.ID
                WHERE SU.ID=@ScheduleDetailUserID AND U.IsDeleted=0 AND SU.IsDeleted=0
            END
    END TRY
    BEGIN CATCH
        SET @Status='S002'--Update Failed
        DECLARE @ErrorDetail AS VARCHAR(MAX)
        SET  @Errordetail ='EXEC dbo.UspUpdateProctorSignalByScheduleUserID @ScheduleDetailUserID='+CAST(ISNULL(@ScheduleDetailUserID,'') AS NVARCHAR(MAX))+',@ProctorSignal='+CAST(ISNULL(@ProctorSignal,'') AS NVARCHAR(MAX))+',@Status='+CAST(ISNULL(@Status,'') AS NVARCHAR(MAX))+',@ScheduleExtensionTime='+CAST(ISNULL(@ScheduleExtensionTime,'') AS NVARCHAR(MAX))
        EXEC [GenerateErrorHandling] @ErrorDetail
        DECLARE @Exception AS NVARCHAR(MAX)  
        SET @Exception=ERROR_MESSAGE() +'-> '+  @ErrorDetail 
        RAISERROR (@Exception, 16, 1)
    END CATCH
SET NOCOUNT OFF;
END
4

1 に答える 1