G
Greg
I have never been a fan of building Input SqlParameters dynamically. I know
ADO.NET does a pretty good job figuring out datatype and size. However, I
like having the control and knowing I can affect the performance by building
them myself.
When I initially wrote our DAL, I built the SqlParameters dynamically
because this is how my clients pretty much demand I do it in the past. It
worked well except for one or two fields. So, I redesigned the DAL to build
the SqlParameters with specific code for each parameter. I added a simple
type that built the commands, as needed, for me:
Public Shared Function BuildUpdateCommand(ByVal tableName As String) As
SqlCommand
If tableName Is Nothing Then Throw New
ArgumentNullException("tableName")
Dim updateCommand As New SqlCommand
Select Case tableName.ToLower
Case "names"
updateCommand.CommandText = "[usp_update_names]"
updateCommand.CommandType =
System.Data.CommandType.StoredProcedure
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@id", System.Data.SqlDbType.VarChar, 6,
"names_id"))
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@me", System.Data.SqlDbType.VarChar, 1,
"names_me"))
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@ty", System.Data.SqlDbType.VarChar, 2,
"names_ty"))
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@lname", System.Data.SqlDbType.VarChar,
20, "names_lname"))
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@fname", System.Data.SqlDbType.VarChar,
15, "names_fname"))
Case "addr"
etc....
Return updateCommand
My prior, dynamic code, looked something like this:
' handler for DataAdapter RowUpdating event
Protected Shared Sub OnRowUpdating(ByVal sender As Object, ByVal e As
SqlRowUpdatingEventArgs)
Dim col As DataColumn
Dim drw As DataRow = e.Row
Dim myParam As SqlParameter
For Each col In drw.Table.Columns
Try
' check the original row against the current row to see if they are
different
If Not (drw(col, DataRowVersion.Current).Equals(drw(col,
DataRowVersion.Original))) Then
' build a parameter for the changed column
myParam = New SqlParameter("@" & col.ColumnName.Remove(0,
col.ColumnName.IndexOf("_") + 1), drw.Item(col).ToString)
e.Command.Parameters.Add(myParam)
Again, the 'dynamic' code worked nice except for 2-3 fields. I was not happy
giving control over to ADO.NET, but it seems to do the job nicely.
So, now my client has informed me there are cases where our client change
the type and size in their sql server tables. Each client maintains there
own sql server database.
Now, I need to go back to the 'dynamic' approach. I am resisting though as I
once again will lose control and will have to trust ADO.NET to build the
correct type and size.
Is there happy middle ground here? Is there a way to have a little more
control over the definition of a SqlParameter but still build it dynamically
or at design time? I will not use the CommandBuilder nor will I query the
sprocs to get this info. Too much overhead.
Greg Robinson
Custom Data Systems, Inc.
www.cds-am.net
ADO.NET does a pretty good job figuring out datatype and size. However, I
like having the control and knowing I can affect the performance by building
them myself.
When I initially wrote our DAL, I built the SqlParameters dynamically
because this is how my clients pretty much demand I do it in the past. It
worked well except for one or two fields. So, I redesigned the DAL to build
the SqlParameters with specific code for each parameter. I added a simple
type that built the commands, as needed, for me:
Public Shared Function BuildUpdateCommand(ByVal tableName As String) As
SqlCommand
If tableName Is Nothing Then Throw New
ArgumentNullException("tableName")
Dim updateCommand As New SqlCommand
Select Case tableName.ToLower
Case "names"
updateCommand.CommandText = "[usp_update_names]"
updateCommand.CommandType =
System.Data.CommandType.StoredProcedure
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@id", System.Data.SqlDbType.VarChar, 6,
"names_id"))
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@me", System.Data.SqlDbType.VarChar, 1,
"names_me"))
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@ty", System.Data.SqlDbType.VarChar, 2,
"names_ty"))
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@lname", System.Data.SqlDbType.VarChar,
20, "names_lname"))
updateCommand.Parameters.Add(New
System.Data.SqlClient.SqlParameter("@fname", System.Data.SqlDbType.VarChar,
15, "names_fname"))
Case "addr"
etc....
Return updateCommand
My prior, dynamic code, looked something like this:
' handler for DataAdapter RowUpdating event
Protected Shared Sub OnRowUpdating(ByVal sender As Object, ByVal e As
SqlRowUpdatingEventArgs)
Dim col As DataColumn
Dim drw As DataRow = e.Row
Dim myParam As SqlParameter
For Each col In drw.Table.Columns
Try
' check the original row against the current row to see if they are
different
If Not (drw(col, DataRowVersion.Current).Equals(drw(col,
DataRowVersion.Original))) Then
' build a parameter for the changed column
myParam = New SqlParameter("@" & col.ColumnName.Remove(0,
col.ColumnName.IndexOf("_") + 1), drw.Item(col).ToString)
e.Command.Parameters.Add(myParam)
Again, the 'dynamic' code worked nice except for 2-3 fields. I was not happy
giving control over to ADO.NET, but it seems to do the job nicely.
So, now my client has informed me there are cases where our client change
the type and size in their sql server tables. Each client maintains there
own sql server database.
Now, I need to go back to the 'dynamic' approach. I am resisting though as I
once again will lose control and will have to trust ADO.NET to build the
correct type and size.
Is there happy middle ground here? Is there a way to have a little more
control over the definition of a SqlParameter but still build it dynamically
or at design time? I will not use the CommandBuilder nor will I query the
sprocs to get this info. Too much overhead.
Greg Robinson
Custom Data Systems, Inc.
www.cds-am.net