我有以下代码,它只执行一个接受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
用于许多不会出现此行为的地方。
还有什么可能导致这种情况?
答案 0 :(得分:4)
要了解为什么从构造函数调用中删除参数方向可以解决问题,请查看SqlParameter
类定义的list of constructors。请注意,没有构造函数采用参数名称SqlDbType
和ParameterDirection
;您实际调用的构造函数是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)}
修正了我的问题。我不知道为什么,如果有人知道我很想知道原因。