Reputation: 1012
I have the requirement to insert records into a SQL table that contains varbinary and image columns.
How do I get 0x00120A011EFD89F94DDA363BA64F57441DE9 (This is the same for all records)
into this
BLOB_TYPE (MY_UDDT(varbinary(18))?
This is what I have so far, everything being very straightforward except for the SqlDbType.Udt parameter definition. With this code I'm getting the error, "Specified type is not registered on the target server.System.Byte[]", I can say 100% the 'User-Defined Data Type' exists on the server. I queried select * from sys.types and it returned the type.
Definition: CREATE TYPE [dbo].[MY_UDDT] FROM varbinary NOT NULL
sql = "INSERT INTO dbo.BLOBS (BLOB_TYPE) VALUES (@BLOB_TYPE);"
cmd = New SqlCommand(sql, conn)
Dim parameter As New SqlParameter("@BLOB_TYPE", SqlDbType.Udt)
With parameter
.SqlDbType = SqlDbType.Udt
.UdtTypeName = "dbo.MY_UDDT"
.Value = blobType
End With
cmd.Parameters.Add(parameter)
cmd.ExecuteNonQuery()
Public ReadOnly Property blobType As Byte()
Get
Dim Str As String = "0x00620A011EFD89F94DDA863BA64F57441DE9"
Dim bytes As Byte() = New Byte(Str.Length * 2 - 1) {}
System.Buffer.BlockCopy(Str.ToCharArray(), 0, bytes, 0, bytes.Length)
Return bytes
End Get
End Property
Upvotes: 1
Views: 2634
Reputation: 48826
There are several things being misunderstood here:
CREATE TYPE
is a UDDT, not a UDT. This is a T-SQL only construct.VARBINARY(18)
instead of VARBINARY
SqlDbType = SqlDbType.VarBinary
Size = 18
Your blobType
function is not sending the hex representation of the string that you are expecting. It is sending the hex values for each character of the string "0x00620A011EFD89F94DDA863BA64F57441DE9". Meaning, the hex value for "0" (i.e. 48 or 0x30), then the hex value for "x" (i.e. 120 or 0x78), and so on for all 38 characters.
You need to take each set of 2 characters after the "0x" (i.e. "00" then "62" then "0A" and so on), convert those to actual bytes, and send the array.
OR
If you have the values in VB as strings and are using SQL Server 2008 or newer, you can pass the string in and have SQL Server convert it for you. You would just modify your INSERT statement to be:
INSERT INTO dbo.BLOBS (BLOB_TYPE) VALUES (CONVERT(VARBINARY(18), @BLOB_TYPE, 1));
The CONVERT
function, using a style of "1" (meaning: a string representation of a binary, starting with "0x") will do the trick. For example:
SELECT CONVERT(VARBINARY(18), '0x00620A011EFD89F94DDA863BA64F57441DE9', 1)
Of course, then you need to change the SqlParameter
properties to be:
SqlDbType = SqlDbType.VarChar
Size = 38
Upvotes: 3
Reputation: 28779
The problem is that the parameter value is a byte array, not an instance of the UDT you are claiming is going to be passed in, and System.Byte[]
is, unsurprisingly, not a registered UDT.
It's confusing, but the "UDT" on the .NET side is used only for UDTs that are created in assemblies (CREATE TYPE ... EXTERNAL NAME
) and not for UDTs based on SQL Server types (called "alias data types" in Books Online). To pass those, do not set the SqlDbType
to Udt
but simply pass in a value of the underlying base type. Basically, these types are only useful on the database end to ensure consistency.
Furthermore, you construct the blob incorrectly -- you need to convert the hexstring to bytes, not the characters that make up the hexstring. If it's really a constant, you can declare it as such. So:
cmd.Parameters.AddWithValue("@BLOB_TYPE", New Byte() { &H00, &H62, &H0A, &H01, &H1E, &HFD, &H89, &HF9, &H4D, &HDA, &H86, &H3B, &HA6, &H4F, &H57, &H44, &H1D, &HE9 })
Should do the trick.
Upvotes: 1
Reputation: 46203
SqlDbType.Udt is for SQLCLR types. In this case, you have a varbinary column so specify SqlDbType.VarBinary along with the max size (18). For the value, pass the byte array containing the raw binary value.
You mention an 18-byte varbinary data type but the data looks to be much longer. If your intent is to convert a string in hex notation to an 18-byte binary value, that's a different question than the one asked here. I suggest you post another question if you need help with that.
Upvotes: 0