我正在使用SQL Server 2000使用PRINT
从表中打印出一些值。对于大多数非字符串数据,我可以转换为nvarchar以便能够打印它,但二进制值尝试使用字符的位表示进行转换。例如:
DECLARE @binvalue binary(4)
SET @binvalue = 0x12345678
PRINT CAST(@binvalue AS nvarchar)
预期:
0×12345678
相反,它打印出两个乱码。
如何打印二进制数据的值?有内置的还是我需要自己动手?
更新:这不是该行的唯一值,所以我不能只打印@binvalue。这更像PRINT N'其他东西'+ ???? + N'more stuff'。不确定这是否有所不同:我本身并没有尝试PRINT @binvalue。
答案 0 :(得分:40)
不要使用
master.sys.fn_varbintohexstr
- 非常慢,未记录,不受支持,可能会在SQL Server的未来版本中消失。
如果您需要将binary(16)
转换为十六进制字符,请使用convert
:
convert(char(34), @binvalue, 1)
为什么34?因为16*2 + 2 = 34
,即“0x” - 2个符号,每个字符加2个符号。
我们尝试在一个有200000行的表上进行2次查询:
select master.sys.fn_varbintohexstr(field)
from table`
select convert(char(34), field, 1)
from table`
第一个运行2分钟,而第二个运行4秒。
答案 1 :(得分:29)
如果您使用的是Sql Server 2005,则可以使用:
print master.sys.fn_varbintohexstr(@binvalue)
我认为2000年不存在,所以你可能不得不自己动手。
答案 2 :(得分:21)
select convert(varchar(max), field , 1)
from table
按using varchar(max)
,您无需担心指定尺寸(种类)。
答案 3 :(得分:5)
添加一个答案,显示将二进制数据转换为十六进制字符串的另一个示例,然后再返回。
我想将最高timestamp
值转换为varchar
:
SELECT
CONVERT(
varchar(50),
CAST(MAX(timestamp) AS varbinary(8)),
1) AS LastTS
FROM Users
返回:
LastTS
==================
0x000000000086862C
注意:使用CONVERT
转换varbinary -> varchar
非常重要。使用CAST
将不起作用:
SELECT
CAST(
CAST(MAX(timestamp) AS varbinary(8))
AS varchar(50) ) AS LastTS
FROM Users
将二进制数据视为字符而不是十六进制值,返回一个空字符串。
将存储的十六进制字符串转换回时间戳:
SELECT CAST(CONVERT(varbinary(50), '0x000000000086862C', 1) AS timestamp)
注意:任何代码都会发布到公共域中。无需归属。
答案 4 :(得分:3)
DECLARE @binvalue binary(4)
SET @binvalue = 0x61000000
PRINT @binvalue
PRINT cast('a' AS binary(4))
PRINT cast(0x61 AS varchar)
不要施放。
转换将二进制文件转换为特定数据库的相应排序规则设置上的文本值。
[开始编辑] 如果您需要字符串变量中的打印值,请使用Eric Z Beard建议的功能。
DECLARE @mybin1 binary(16)
DECLARE @s varchar(100)
SET @mybin1 = 0x098F6BCD4621D373CADE4E832627B4F6
SET @s = 'The value of @mybin1 is: ' + sys.fn_varbintohexsubstring(0, @mybin1,1,0)
PRINT @s
如果由于服务器版本而无法使用此功能,或者因为它需要特殊权限,则可以创建自己的功能。
要了解如何在SQL Server 2005 Express Edition中实现该功能,您可以执行:
sp_helptext 'fn_varbintohexsubstring'
答案 5 :(得分:2)
我在查找SQL Server 2005中'hashbytes'函数返回的十六进制值时寻找类似问题的解决方案时遇到了这个问题。
可悲的是,在这个版本的SQL Server中,CONVERT似乎根本不起作用,只有fn_varbintohexsubstring做正确的事情:
我做了:
DECLARE @binvalue binary(4)
SET @binvalue = 0x12345678
PRINT 'cast(@binvalue AS nvarchar): ' + CAST(@binvalue AS nvarchar)
PRINT 'convert(varchar(max), @binvalue, 0): ' + CONVERT(varchar(max), @binvalue, 0)
PRINT 'convert(varchar(max), @binvalue, 1): ' + CONVERT(varchar(max), @binvalue, 1)
PRINT 'convert(varchar(max), @binvalue, 2): ' + CONVERT(varchar(max), @binvalue, 2)
print 'master.sys.fn_varbintohexstr(@binvalue): ' + master.sys.fn_varbintohexstr(@binvalue)
以下是我在SQL Server 2005中获得的结果(
cast(@binvalue AS nvarchar): 㐒硖
convert(varchar(max), @binvalue, 0): 4Vx
convert(varchar(max), @binvalue, 1): 4Vx
convert(varchar(max), @binvalue, 2): 4Vx
master.sys.fn_varbintohexstr(@binvalue): 0x12345678
('4Vx之前实际上是一个不可打印的角色 - 我发布了一张图片,但我还没有足够的分数。)
编辑:只是为了添加 - 在SQL Server 2008 R2上,使用以下输出修复了CONVERT的问题:
cast(@binvalue AS nvarchar): 㐒硖
convert(varchar(max), @binvalue, 0): 4Vx
convert(varchar(max), @binvalue, 1): 0x12345678
convert(varchar(max), @binvalue, 2): 12345678
master.sys.fn_varbintohexstr(@binvalue): 0x12345678
答案 6 :(得分:0)
该主题中的tl; dr过多:(将尝试在this answer之后对其进行修复。
with
sq1 as (select '41424344' as v), -- this is 'ABCD'
-- Need binary size, otherwise it sets binary(30) in my case
sq2 as (select v, convert(binary(4), v, 2) as b from sq1),
sq3 as (select b, v, convert(varchar, b, 2) as v1 from sq2)
--
select b, v, v1 from sq3
where v = v1
;
输出为:
b |v |v1 |
----|--------|--------|
ABCD|41424344|41424344|
另请参阅:documentation