【问题标题】:List Parameter's object name gets Prefixed with @ outside of ForEach Loop列表参数对象名称在 ForEach 循环外以 @ 为前缀
【发布时间】:2020-05-20 01:25:57
【问题描述】:

在传递给存储过程之前,所有参数都会以@为前缀。 IE, 在我的 foreach 循环区域之外,从第二次迭代开始,所有参数名称都将以 @ 为前缀,并在调用存储过程时从第二次迭代中获取异常消息

{"过程或函数 UspUpdateProctorSignalByScheduleUserID 也有 指定了许多参数。"}

下面是sn-ps的部分代码:

[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.对于第二次迭代

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.对于第二次迭代

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

这里的属性从第二次迭代开始改变

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

在 foreach 循环中声明和初始化时,同样的 sn-ps 可以完美运行。

但在 foreach 循环中,条件 if (proctorStatus == "PAUSE") 会检查是否删除特定索引 3 处的列表 parameters.RemoveAt(3);

是否可以使用LINQLambda 运算符编写相同的条件,即通过在循环的每次迭代中删除特定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

【问题讨论】:

  • 你能显示存储过程吗?
  • 用 SP @JamesS 的更新副本编辑了帖子
  • 在您的第二次迭代中,您是否有任何理由为大多数存储的 proc 参数加上两个 @

标签: c# asp.net list linq


【解决方案1】:

标题与您的描述不符,但从我得到的信息来看,这是您要查找的内容:

parameters.Remove(x=>(x as SqlParameter)?.ParameterName == "ProctorSignal");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2014-02-18
    • 2015-05-06
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多