【问题标题】:SQL Server procedure has too many arguments specifiedSQL Server 过程指定的参数过多
【发布时间】:2018-06-30 19:54:55
【问题描述】:

我得到了错误

过程或函数有许多指定的参数

但只是有时。这是一个 REST API,手机调用此函数来验证用户。今天只有 1-2 部手机,它们每分钟拨打一次电话。

它在大多数情况下运行良好,但有时我会收到此错误代码。

为了看看有什么问题,我做了一个小循环,将参数收集到一个字符串中。有时它们是两个@GUID@Datum,有时会重复它们自己。

这是VB代码:

Public Shared Sub validatePhone(secretKey As String, ByRef _RS As phoneData, Fnr As Integer)
    Dim connStr As String = System.Configuration.ConfigurationManager.AppSettings("ConnStringSQL")
    Dim Conn As SqlConnection = New System.Data.SqlClient.SqlConnection(connStr)
    Dim _theString As New System.Text.StringBuilder

    Try
        _RS.message = ""
        _RS.status = True
        Dim Status As Integer = 0
        Dim _GUID As Guid = New Guid(secretKey)

        Try
            Conn.Open()
        Catch ex As Exception
        End Try

        cmd.Connection = Conn
        Apt.SelectCommand = cmd
        cmd.CommandType = CommandType.StoredProcedure
        cmd.CommandText = "API2017_checkPhone"

        cmd.Parameters.Clear()
        cmd.Parameters.Add("@GUID", SqlDbType.UniqueIdentifier).Value = _GUID
        cmd.Parameters.Add("@Datum", SqlDbType.SmallDateTime).Value = Now

        For Each item As SqlParameter In cmd.Parameters
            _theString.Append(item.ParameterName & ";")
        Next

        Apt.Fill(ds, "DataCheckPhone")

        If ds.Tables("DataCheckPhone").Rows.Count > 0 Then
            With ds.Tables("DataCheckPhone").Rows(0)
                Status = .Item("spStatus")

                If Status = 0 Then
                    _RS.Namn = .Item("Namn")
                    _RS.SalesID = .Item("SalesID")
                    _RS.Anlaggning = .Item("Anlaggning")
                    _RS.Anlnr = .Item("Anlnr")
                    Funktions.URLEncodeStr(_RS.Namn)
                    Funktions.URLEncodeStr(_RS.Anlaggning)
                End If
            End With
        Else
            Dim _Lnum As Integer
            Funktions.Logg(Fnr & ": " & "Fatal error", 999, _Lnum, 0)
            _RS.message = "Error 999:" & _Lnum.ToString
            Return
        End If

    Catch ex As Exception
        _RS.status = False
        _RS.Anlaggning = Nothing
        _RS.Anlnr = 0
        _RS.Namn = Nothing
        _RS.SalesID = Nothing
        Dim _Lnum As Integer
        Funktions.Logg(Fnr & ": " & ex.Message & "{" & _theString.ToString & "}", 999, _Lnum, 0)
        _RS.message = "Error 999:" & _Lnum.ToString

    Finally
        ds.Tables.Clear()

        Try
            ds.Tables("DataCheckPhone").Dispose()
        Catch ex As Exception
        End Try
    End Try

    Try
        Conn.Close()
        Conn.Dispose()
    Catch ex As Exception
    End Try
End Sub

这里是存储过程:

ALTER PROCEDURE [dbo].[API2017_checkPhone]
    @GUID as uniqueidentifier,
    @Datum as smalldatetime
AS
    DECLARE @Status AS INT
    DECLARE @Anlaggning AS NVARCHAR(50)
    DECLARE @Namn AS NVARCHAR(50)
    DECLARE @Anlnr AS INT
    DECLARE @SalesID AS uniqueidentifier
    DECLARE @LockedSalesman AS BIT
    DECLARE @LockedAnlaggning AS BIT

    SET @Status = 0

    IF EXISTS (SELECT * FROM KK2017_connectedPhones WHERE [guid] = @guid)
    BEGIN
        SET @status = 0
        SET @salesID = (SELECT salesID FROM KK2017_connectedPhones 
                        WHERE [guid] = @guid)
        SET @Anlnr = (SELECT anlnr FROM KK2017_Säljare WHERE salesID = @salesID)
        SET @Namn = (SELECT Namn FROM KK2017_Säljare WHERE salesID = @salesID)
        SET @Anlaggning = (SELECT namn FROM KK2017_Anlaggning WHERE anlnr = @Anlnr)
        SET @LockedSalesman = (SELECT locked FROM KK2017_Säljare WHERE salesID = @salesID)

        UPDATE KK2017_Säljare 
        SET inloggad = @Datum 
        WHERE salesID = @SalesID

        IF @LockedSalesman = 1 
        BEGIN
            SET @Status = 2
        END

        SET @LockedAnlaggning = (SELECT locked FROM KK2017_Anlaggning 
                                 WHERE AnlNr = @Anlnr)

        IF @LockedAnlaggning = 1
        BEGIN
            SET @status = 3
        END
    END
    ELSE
       SET @status = 1

    SELECT 
        @Status AS spStatus, 
        @Anlaggning AS Anlaggning, 
        @anlnr AS anlnr, 
        @Namn AS namn, 
        @SalesID AS salesID

我一定是做错了什么,但看不到。

如果有人有建议,我将不胜感激。

/克拉斯

【问题讨论】:

  • 请将错误信息添加到您的问题中
  • cmd 是在哪里定义的?每次运行此代码时只需创建一个新的cmd 对象,重用该对象并没有明显的节省。它只会让你容易出现这样的问题。

标签: asp.net sql-server


【解决方案1】:

您遇到了线程问题,因为您将cmd 定义为shared,这意味着只有一个实例为所有传入请求提供服务。有时两个线程同时在添加参数,两个线程都以四个结束,因此报错。

这里的标准模式是将cmd 声明为局部变量,并在每次调用函数时实例化一个新实例。对此的开销可以忽略不计。

此外,避免在多线程应用程序(例如 Web 服务)中使用 shared 变量。对于所有用户和所有线程,只有一个变量副本,而且 99% 的时间这不是您真正想要的。对于另外 1%,您通常会使用应用程序变量或 HttpCache。在这种情况下,您应该使用局部变量。

【讨论】:

  • 感谢您的所有回答。 CMD 在子程序之外声明。将立即尝试删除 SHARED 并使用局部变量。我还发现我在 try...Catch 之后清理了连接(conn)。但是里面我有一个回报所以我并不总是清理然后连接。
  • 现在我已将所有共享功能更改为不共享。该服务已经一夜没有了,我在三台计算机上进行了测试,每台计算机都有 1000 个问题....没有错误:-) 非常感谢您的帮助。
  • 很高兴听到这个消息!很高兴它正在工作。不要忘记将此问题标记为已回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 2023-03-26
  • 2014-02-08
相关资源
最近更新 更多