Next generation's garbage RSS 2.0
# Thursday, March 25, 2010

Wanted a generic way to pass a DataTable as a parameter to SqlCommand as a TVP (Table Value Parameter). It automatically creates the, IMHO, superfluous User-Defined Table Types. Here's what I have so far:

<Runtime.CompilerServices.Extension()> _
    Sub AddTableParameter(ByVal cmd As SqlCommand, ByVal n As String, ByVal dt As DataTable)
        Static typeXlat As Dictionary(Of System.Type, SqlDbType)
        If typeXlat Is Nothing Then
            typeXlat = New Dictionary(Of System.Type, SqlDbType)
            typeXlat.Add(GetType(Int64), SqlDbType.BigInt)
            typeXlat.Add(GetType(Int32), SqlDbType.Int)
            typeXlat.Add(GetType(Int16), SqlDbType.SmallInt)
            typeXlat.Add(GetType(Byte), SqlDbType.TinyInt)
            typeXlat.Add(GetType(SByte), SqlDbType.TinyInt)
            typeXlat.Add(GetType(Boolean), SqlDbType.Bit)
            typeXlat.Add(GetType(String), SqlDbType.VarChar)
            typeXlat.Add(GetType(Byte()), SqlDbType.VarBinary)
            typeXlat.Add(GetType(DateTime), SqlDbType.DateTime)
            typeXlat.Add(GetType(DateTimeOffset), SqlDbType.DateTimeOffset)
            typeXlat.Add(GetType(Char), SqlDbType.Char)
            typeXlat.Add(GetType(Single), SqlDbType.Real)
            typeXlat.Add(GetType(Double), SqlDbType.Float)
            typeXlat.Add(GetType(Decimal), SqlDbType.Decimal)
            typeXlat.Add(GetType(Guid), SqlDbType.UniqueIdentifier)
            typeXlat.Add(GetType(Xml.XmlDocument), SqlDbType.Xml)
        End If

        'assembly the typename and spec
        Dim tabletypedef As New List(Of String)
        Dim parm As New SqlParameter(n, SqlDbType.Structured)
        parm.Value = dt

        For Each c As DataColumn In dt.Columns
            Dim s As SqlDbType = SqlDbType.Variant
            If typeXlat.ContainsKey(c.DataType) Then s = typeXlat(c.DataType)
            tabletypedef.Add(c.ColumnName + " " + s.ToString)
        Next
        Dim tabledef = String.Join(",", tabletypedef.ToArray)
        Dim typename = "autotype_" + tabledef
        parm.TypeName = "[" + typename + "]"

        'create the type if needed
        Using cmd2 = New SqlCommand("select count(*) from sys.types where is_table_type=1 and name='" + typename + "'", cmd.Connection)
            If cmd2.ExecuteScalar() = 0 Then
                cmd2.CommandText = "create type [" + typename + "] as table(" + tabledef + ")"
                cmd2.ExecuteNonQuery()
            End If
        End Using

        'add the parm referencing the typename
        cmd.Parameters.Add(parm)
    End Sub

Thursday, March 25, 2010 7:54:18 PM (US Mountain Standard Time, UTC-07:00)  #    Comments [0] -
.NET | SQL
Archive
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910
All Content © 2013, Hafthor Stefansson - Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way. - Sign In