¿Cómo puedo imprimir un valor binario como hexadecimal en TSQL?


Estoy usando SQL Server 2000 para imprimir algunos valores de una tabla usando PRINT. Con la mayoría de los datos que no son de cadena, puedo convertir a nvarchar para poder imprimirlos, pero los valores binarios intentan convertir utilizando la representación de bits de caracteres. Por ejemplo:

DECLARE @binvalue binary(4)
SET @binvalue = 0x12345678
PRINT CAST(@binvalue AS nvarchar)

Esperado:

0x12345678

En su lugar, imprime dos caracteres galimatías.

¿Cómo puedo imprimir el valor de los datos binarios? ¿Hay una incorporada o necesito rodar la mía?

Actualizar: Este no es el único valor en la línea, así que no puedo simplemente IMPRIMIR @binvalue. Es algo más como IMPRIMIR y otras cosas + ???? + N'more stuff'. No estoy seguro de si eso hace una diferencia: no intenté simplemente IMPRIMIR @binvalue por sí mismo.

Author: Tadmas, 2008-09-16

6 answers

Si estuviera en Sql Server 2005 podría usar esto:

print master.sys.fn_varbintohexstr(@binvalue)

No creo que eso exista en 2000, sin embargo, por lo que podría tener que rodar su propia.

 30
Author: Eric Z Beard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-11 21:00:33

No use master.sys.fn_varbintohexstr - es terriblemente lento, indocumentado, sin soporte, y podría desaparecer en una versión futura de SQL Server.

Si necesita convertir binary(16) a caracteres hexadecimales, use

convert(char(34), @binvalue, 1)

¿Por qué 34? porque 16*2 + 2 = 34, eso es " 0x " - 2 símbolos, más 2 símbolos para cada carácter.

Intentamos hacer 2 consultas en una tabla con 200000 filas:

  1. select master.sys.fn_varbintohexstr(field)
    from table`
    
  2. select convert(char(34), field, 1)
    from table`
    

El primero se ejecuta 2 minutos, mientras que el segundo - 4 segundos.

 35
Author: Ihor B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-06 10:28:00
select convert(varchar(max), field , 1) 
from table

Por using varchar(max) no tendrá que preocuparse por especificar el tamaño (tipo de).

 20
Author: Charlie Affumigato,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-06 10:30:36
DECLARE @binvalue binary(4)
SET @binvalue = 0x61000000
PRINT @binvalue 
PRINT cast('a' AS binary(4))
PRINT cast(0x61 AS varchar)

No lanzar.

Casting convierte el binario a texto por valor en la configuración de intercalación correspondiente para la base de datos específica.

[Comenzar editar] Si necesita el valor impreso en una variable string utilice la función sugerida por 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

Si esta función no está a su disposición debido a las versiones del servidor o porque necesita permisos especiales, puede crear su propia función.

Para ver cómo se implementó esa función en SQL Server 2005 Express edition se puede ejecutar:

sp_helptext 'fn_varbintohexsubstring'
 3
Author: Ricardo C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 04:17:44

Añadiendo una respuesta que muestra otro ejemplo de convertir datos binarios en una cadena hexadecimal, y viceversa.

Quiero convertir el valor más alto de timestamp en varchar:

SELECT 
   CONVERT(
      varchar(50), 
      CAST(MAX(timestamp) AS varbinary(8)), 
      1) AS LastTS
FROM Users

Que devuelve:

LastTS
==================
0x000000000086862C

Nota: Es importante que utilices CONVERT para convertir varbinary -> varchar. Usar CAST no funcionará:

SELECT 
   CAST(
      CAST(MAX(timestamp) AS varbinary(8)) 
      AS varchar(50) ) AS LastTS
FROM Users

Tratará los datos binarios como caracteres en lugar de valores hexadecimales, devolviendo una cadena vacía.

Inverso it

Para volver a convertir la cadena hexadecimal almacenada en una marca de tiempo:

SELECT CAST(CONVERT(varbinary(50), '0x000000000086862C', 1) AS timestamp)

Nota : Cualquier código es liberado al dominio público. No se requiere atribución.

 3
Author: Ian Boyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-15 03:12:46

Me encontré con esta pregunta mientras buscaba una solución a un problema similar mientras imprimía el valor hexadecimal devuelto por la función 'hashbytes' en SQL Server 2005.

Lamentablemente en esta versión de SQL Server, CONVERT no parece funcionar en absoluto, solo fn_varbintohexsubstring hace lo correcto:

Lo hice:

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)

Aquí está el resultado que obtuve en 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

(en realidad hay un carácter no imprimible antes de los ' 4VX's-publicaría una imagen, pero Todavía no tengo suficientes puntos).


Edit : Solo para agregar SQL Server 2008 R2 el problema con CONVERT se soluciona con la siguiente salida:

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
 2
Author: David Claughton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-16 09:25:45