Search code examples
vb.netsqlparameter

Is there a better way to call a Stored Procedure with SqlParameters in VB?


Anyone know of a better way to create and initialize SqlParameters in VB.NET? Using 3 lines per variable seems quite excessive. Unfortunately the constructors for this class are rather ridiculous, so I'm thinking of just writing my own sub for initializing each parameter. This is how I've been doing it.

Dim ID As New SqlParameter("@ID", SqlDbType.Int)
ID.Value = val
query.Parameters.Add(ID)

Here is the full code that I use for even a simple Store Procedure which only takes a single argument. I have some however which take 15-20 and that's a LOT of lines of code using this clunky method.

Dim query As New SqlCommand("spGetInitStatusEntry", connection)
query.CommandType = CommandType.StoredProcedure
Dim ID As New SqlParameter("@ID", SqlDbType.Int)
ID.Value = val
query.Parameters.Add(ID)
Dim dt As New DataTable
Dim da As New SqlDataAdapter(query)
da.Fill(dt)

Final Implementation

I created the following Module, as recommended, with two supporting <Extension()>s.

Module TcomExtensions
    <System.Runtime.CompilerServices.Extension()> _
    Public Sub AddParameter(ByRef dbCommand As SqlCommand, ByVal parameterName As String, _
            ByVal parameterValue As Object, ByVal dbType As SqlDbType)

        Dim dbParameter As SqlParameter = Nothing
        dbParameter = dbCommand.CreateParameter

        dbParameter.ParameterName = parameterName
        dbParameter.Value = parameterValue
        dbParameter.DbType = dbType

        dbCommand.Parameters.Add(dbParameter)
    End Sub

    <System.Runtime.CompilerServices.Extension()> _
    Public Function ToDataTable(ByVal value As SqlCommand) As DataTable
        Dim dt As New DataTable
        Using da As New SqlDataAdapter(value)
            da.Fill(dt)
        End Using
        Return dt
    End Function
End Module

And my implementation becomes as follows:

Dim spPrefill As New SqlCommand("spGetPrefillStatusEntry", connection) With {.CommandType = CommandType.StoredProcedure}
'Only one line per added parameter.
spPrefill.AddParameter("@ID", val, SqlDbType.Int)
'Populate the table.
dt = spPrefill.ToDataTable()

Solution

  • With those extension...

     <System.Runtime.CompilerServices.Extension()> _
    Public Sub AddParameterValue(ByRef dbCommand As System.Data.Common.DbCommand, ByVal parameterName As String, ByVal parameterValue As Object)
        dbCommand.AddParameter(parameterName, parameterValue)
    End Sub
    
    
    <System.Runtime.CompilerServices.Extension()> _
    Public Sub AddParameter(ByRef dbCommand As System.Data.Common.DbCommand, ByVal parameterName As String, Optional ByVal parameterValue As Object = Nothing, Optional ByVal sourceColumn As String = "")
        Dim dbParameter As System.Data.Common.DbParameter = Nothing
    
    
        dbParameter = dbCommand.CreateParameter
    
        dbParameter.ParameterName = parameterName
        dbParameter.Value = parameterValue
        dbParameter.SourceColumn = sourceColumn
    
        dbCommand.Parameters.Add(dbParameter)
    
    End Sub
    

    ...you'll be able to add a parameter with 1 line of code

    Dim query As New SqlCommand("spGetInitStatusEntry", connection)
    query.CommandType = CommandType.StoredProcedure
    query.AddParameterValue("@ID", key)
    Dim dt As New DataTable
    Dim da As New SqlDataAdapter(query)
    da.Fill(dt) 
    

    The function is pretty generic and the parameter type isn't specified but you can add it as parameter if you really need it.