SQL参数值被截断

时间:2018-03-05 16:52:23

标签: sql-server vb.net

我有以下代码,它只执行一个接受1个参数的存储过程。

Public Function GetData(ByVal Faccode As String, Optional ByRef s As String = "") As DataSet

    Dim params As SqlParameter() = {New SqlParameter("@aFacilityCode", SqlDbType.VarChar, ParameterDirection.Input)}

    ' Set the value
    params(0).Value = "SW29" 'Faccode

    Try
        Dim DSet As DataSet = RunProcedure("usp_FL_GetAllData", params, "ContactData")
        Return DSet
    Catch ex As Exception
        Return Nothing
    End Try

End Function

Protected Overloads Function RunProcedure( _
  ByVal storedProcName As String, _
  ByVal parameters As IDataParameter(), _
  ByVal tableName As String) _
  As DataSet

  Dim dataSet As New dataSet

  Try
    myConnection.Open()
    Dim sqlDA As New SqlDataAdapter
    sqlDA.SelectCommand = BuildQueryCommand(storedProcName, parameters)
    sqlDA.Fill(dataSet, tableName)

    Return dataSet
  Catch ex As Exception
    Return Nothing
  Finally
    If myConnection.State = ConnectionState.Open Then
      myConnection.Close()
    End If
  End Try
End Function

Private Function BuildQueryCommand( _
  ByVal storedProcName As String, _
  ByVal parameters As IDataParameter()) _
  As SqlCommand

  Dim command As New SqlCommand(storedProcName, myConnection)
  command.CommandType = CommandType.StoredProcedure

  Dim parameter As SqlParameter
  For Each parameter In parameters
    command.Parameters.Add(parameter)
  Next

  Return command

End Function

SQL过程的定义如下:

CREATE PROCEDURE [dbo].[usp_FL_GetAllData]
(
   @aFacilityCode VARCHAR(10)
)

当我运行该软件时,SQL事件探查器显示正在进行此调用:

exec usp_FL_GetAllData @aFacilityCode='S'

最初,我在Faccode函数中为我的参数指定了值GetData,但注意到这个奇怪的截断,这就是为什么我现在正在对该值进行硬编码。

我唯一能想到的是SQL过程将参数定义为varchar(1),但它被定义为10,所以我不知道为什么会发生这种情况。 RunProcedure用于许多不会出现此行为的地方。

还有什么可能导致这种情况?

3 个答案:

答案 0 :(得分:4)

要了解为什么从构造函数调用中删除参数方向可以解决问题,请查看SqlParameter类定义的list of constructors。请注意,没有构造函数采用参数名称SqlDbTypeParameterDirection;您实际调用的构造函数是this one,其第三个参数是参数大小。由于ParameterDirection.Input的支持值为1,因此您明确将参数的大小设置为一个字符。

当您调用未明确指定大小的构造函数时,该对象会根据您指定的值推断参数的大小,如documentation for that property中所述。

答案 1 :(得分:2)

这会对您的代码进行一些重要更改。它确实解决了参数长度问题,但您需要检查它是否真的有用。

's was not used, and ByRef is a code smell in .Net
Public Function GetData(ByVal Faccode As String) As DataSet
    Dim params As New SqlParameter("@aFacilityCode", SqlDbType.VarChar, 10)

    If String.IsNullOrEmpty(Faccode) Then Faccode = "SW29"
    params.Value = Faccode

    'Removed Try/Catch handler. It's NEVER a good idea to just swallow exceptions like that. Let the exception bubble up to higher level code that knows how to handle it.
    Return RunProcedure("usp_FL_GetAllData", "ContactData", params)    
End Function

'Note the change to SqlParameter. IDataParameter does not have a Length or Size property. That MIGHT be your problem.
'Also note the use of ParamArray... required changing the order of the arguments, but helped simplify code in the first function
Protected Overloads Function RunProcedure( _
  ByVal storedProcName As String, ByVal tableName As String, _
  ByVal ParamArray parameters() As SqlParameter) _
  As DataSet

    Dim dataSet As New dataSet 
    Using myConnection As New SqlConnection("string here"), _
          command As SqlCommand = BuildQueryCommand(storedProcName, parameters), _
          sqlDA As New SqlDataAdapter(command)

        command.Connection = myConnection
        sqlDA.Fill(dataSet, tableName) '.Fill() will open the connection for you if needed
    End Using
    Return dataSet
End Function

Private Function BuildQueryCommand( _
   ByVal storedProcName As String, _
  ByVal ParamArray parameters() As SqlParameter) _
  As SqlCommand

    Dim command As New SqlCommand(storedProcName)
    command.CommandType = CommandType.StoredProcedure

    If parameters IsNot Nothing Then command.Parameters.AddRange(parameters)    
    Return command    
End Function

请注意,这些更改可能会影响您应用程序中的其他代码,但它们很重要。

答案 2 :(得分:0)

从此更改GetData的第一行:

Dim params As SqlParameter() = {New SqlParameter("@aFacilityCode", SqlDbType.VarChar, ParameterDirection.Input)}

对此:

Dim params As SqlParameter() = {New SqlParameter("@aFacilityCode", SqlDbType.VarChar)}

修正了我的问题。我不知道为什么,如果有人知道我很想知道原因。