将字符串数据插入到Varbinary用户定义的数据类型列SQL Server .NET中

时间:2014-10-13 16:51:16

标签: sql-server vb.net sqlclr sqlcommand user-defined-types

我需要将记录插入到包含varbinary和image列的SQL表中。

我如何获得0x00120A011EFD89F94DDA363BA64F57441DE9(所有记录都相同)

进入这个

BLOB_TYPE(MY_UDDT(varbinary(18))?

这是我到目前为止所做的一切,除了SqlDbType.Udt参数定义外,一切都非常简单。使用此代码我收到错误,"指定的类型未在目标服务器上注册.System.Byte []",我可以说100%用户定义的数据键入'存在于服务器上。我从sys.types查询select *并返回了类型。

定义: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

3 个答案:

答案 0 :(得分:3)

这里有几件事被误解了:

  • 用户定义数据类型(UDDT)和用户定义类型(UDT)之间存在很大差异,但可以理解的是,鉴于名称的相似性,人们会感到困惑。
    • 您通过CREATE TYPE创建的是UDDT,而不是UDT。这是一个仅限T-SQL的构造。
    • 注意将来:指定可变长度数据类型时,请务必指定长度: VARBINARY(18)代替VARBINARY
    • UDT是SQLCLR构造。以下是MSDN上以这种方式使用UDT的示例:
      http://msdn.microsoft.com/library/ms131080.aspx
  • 你这里不需要任何东西。你只需要设置:
    • SqlDbType = SqlDbType.VarBinary
    • Size = 18
  • 您的blobType函数未发送您期望的字符串的十六进制表示。它正在为字符串“0x00620A011EFD89F94DDA863BA64F57441DE9”的每个字符发送十六进制值。含义,“0”的十六进制值(即48或0x30),然后是“x”的十六进制值(即120或0x78),依此类推所有38个字符。

    你需要在“0x”之后取每组2个字符(即“00”然后“62”然后“0A”等等),将它们转换为实际字节,然后发送数组。

    如果您将VB中的值作为字符串并使用SQL Server 2008或更高版本,则可以传入该字符串并让SQL Server为您进行转换。您只需将INSERT语句修改为: INSERT INTO dbo.BLOBS (BLOB_TYPE) VALUES (CONVERT(VARBINARY(18), @BLOB_TYPE, 1));

    CONVERT函数,使用样式“1”(意思是:二进制的字符串表示,以“0x”开头)将起作用。例如:

    SELECT CONVERT(VARBINARY(18), '0x00620A011EFD89F94DDA863BA64F57441DE9', 1)

    当然,您需要将SqlParameter属性更改为:

    • SqlDbType = SqlDbType.VarChar
    • Size = 38

答案 1 :(得分:1)

问题是参数值是一个字节数组,而不是您声称要传入的UDT的实例,而System.Byte[],不出所料,不是注册的UDT。

令人困惑,但.NET端的“UDT”仅用于在程序集(CREATE TYPE ... EXTERNAL NAME)中创建的UDT,而不用于基于SQL Server类型的UDT(称为“别名数据类型”)在线书籍)。要传递这些内容,请 not SqlDbType设置为Udt,但只需传入基础类型的值。基本上,这些类型仅在数据库端有用,以确保一致性。

此外,您错误地构造了blob - 您需要将hexstring转换为字节,而不是构成hexstring的字符。如果它真的是一个常数,你可以这样声明它。所以:

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 })

应该做的伎俩。

答案 2 :(得分:0)

SqlDbType.Udt适用于SQLCLR类型。在这种情况下,您有一个varbinary列,因此请指定SqlDbType.VarBinary以及最大大小(18)。对于该值,传递包含原始二进制值的字节数组。

您提到了一个18字节的varbinary数据类型,但数据看起来要长得多。如果您的目的是将十六进制表示法中的字符串转换为18字节的二进制值,那么这个问题与此处提出的问题不同。如果您需要帮助,我建议您发布另一个问题。