【问题标题】:How to convert nvarchar to varbinary accurately如何准确地将 nvarchar 转换为 varbinary
【发布时间】:2013-07-09 17:54:39
【问题描述】:

我有一个表,其列 [password] 存储为 nvarchar(max)。我想把它转换成varbinary(max)

我创建了一个名为[temp] 的新列并将其声明为varbinary(max)。然后我用CONVERT更新了:

update tempuser set [temp]=CONVERT(varbinary(max), CONVERT(nvarchar(max),[password]))

现在 [temp] 列中的值不同。例如,[password] 的一个值以此开头:

0x3E6AFF88...

[temp] 中对应的条目以:

0x30783345...

同样当[password]NULL 时,[temp] 变为0x4E554C4C

【问题讨论】:

  • 为什么你认为它们应该是一样的?
  • 同意@Goat。您正在转换一个恰好 看起来 像二进制值的字符串,因为它以 0x 开头。不幸的是,这些不是一回事。试试CONVERT(VARBINARY(MAX), [password]), 1)

标签: sql database sql-server-2008


【解决方案1】:

您正在转换一个恰好看起来像二进制值的字符串,因为它以0x 开头。不幸的是,这些不是一回事,为了让 SQL Server 理解您希望将字符串解释为要直接转换的实际二进制值,而不是将字符串转换为其二进制表示,您需要使用样式参数:

UPDATE dbo.tempuser -- please always use the schema prefix
  SET [temp] = CONVERT(VARBINARY(MAX), [password], 1); -- and semi-colons

请注意,将NVARCHAR(MAX) 转换为NVARCHAR(MAX) 是不必要的。

现在,有可能因为某些原因你选择了NVARCHAR(MAX),该列包含无法转换的垃圾,所以你可能会遇到这个错误:

消息 8114,级别 16,状态 5
将数据类型 nvarchar 转换为 varbinary 时出错。

在这种情况下,您需要找到不以 0x 开头的值(或包含不合格字符)并修复它们。

【讨论】:

  • 有没有办法将整个日期原样复制到数据类型为 varbinary 的列中?
  • @user2429070 我不明白你的意思。这就是更新所做的,但原始值必须能够转换为二进制文件。由于您将“二进制”值存储在字符串列中,因此无法保证它们都可以转换为二进制。
【解决方案2】:

看起来您的密码字段实际上并不是一个 varbinary,尽管看起来像一个。

运行这些作为示例:

SELECT CAST('0x3E6AFF88BEB29D9B234B9E5A5AD329D8D3F33200EC4EE02749C56AD58D040976' AS varbinary(max))
SELECT CAST(CAST('0x3E6AFF88BEB29D9B234B9E5A5AD329D8D3F33200EC4EE02749C56AD58D040976' AS varbinary(max))AS VARCHAR(MAX))

SELECT CAST('dog' AS VARBINARY(MAX))
SELECT CAST(CAST('dog' AS VARBINARY(max))AS VARCHAR(MAX))

你看到你的结果等同于你的初始字符串,只是 varbinary 格式。

【讨论】:

  • 这并不完全正确。试试这个:SELECT CAST(123456 AS VARBINARY(MAX));,你会看到结果是0x0001E240,其中有一个EVARBINARY 可以使用从AF 的字母
  • 嗯,有趣,谢谢。甚至我的“狗”示例也有一封我没有注意到的信。
【解决方案3】:

Hart Co's answer shown一样,使用以下代码将密码转换为十六进制数字。

UPDATE dbo.tempuser SET [temp] = CONVERT(VARBINARY(MAX), [password], 1);

如果你有

消息 8114,级别 16,状态 5
将数据类型 nvarchar 转换为 varbinary 时出错。

这意味着您的一个或多个密码包含一个有效的十六进制字符串。容易忽略的原因之一是您有奇数个字符。您可以使用以下代码检查导致错误的行:

SELECT id, TRY_CONVERT(VARBINARY(MAX), [password], 1) AS try_convert
FROM tempuser
WHERE try_convert IS NULL

TRY_CONVERT 如果发现无法转换的内容,将返回 NULL,而不是返回错误。

如果你得到的行包含奇数个字符,你可以使用RIGHT 函数左填充零以使它们有效。

CONVERT(
    varbinary(MAX),
    RIGHT('000000000000'+SUBSTRING([password], 3, LEN([reg_address])), 16),
    2
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    相关资源
    最近更新 更多