web-dev-qa-db-fra.com

Comment imprimer une valeur binaire en hexadécimal dans SQL?

J'utilise SQL Server 2000 pour imprimer certaines valeurs d'une table à l'aide de PRINT. Avec la plupart des données non-chaîne, je peux convertir en nvarchar pour pouvoir les imprimer, mais les valeurs binaires tentent de convertir en utilisant la représentation binaire des caractères. Par exemple:

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

Attendu:

0x12345678

Au lieu de cela, il imprime deux caractères charabia.

Comment imprimer la valeur des données binaires? Y a-t-il un système intégré ou dois-je rouler le mien?

Mise à jour: Ce n'est pas la seule valeur sur la ligne, donc je ne peux pas simplement IMPRIMER @binvalue. C'est plus comme PRINT N'other stuff '+ ???? + N'more stuff '. Je ne sais pas si cela fait une différence: je n'ai pas simplement essayé PRINT @binvalue.

35
Tadmas

Si vous étiez sur Sql Server 2005, vous pouvez utiliser ceci:

print master.sys.fn_varbintohexstr(@binvalue)

Je ne pense pas que cela existe en 2000, donc vous devrez peut-être lancer le vôtre.

29
Eric Z Beard

N'utilisez pas master.sys.fn_varbintohexstr - c'est terriblement lent, non documenté, non pris en charge et pourrait disparaître dans une future version de SQL Server.

Si vous devez convertir binary(16) en char hexadécimal, utilisez convert:

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

Pourquoi 34? parce que 16*2 + 2 = 34, c'est "0x" - 2 symboles, plus 2 symboles pour chaque caractère.

Nous avons essayé de faire 2 requêtes sur une table avec 200000 lignes:

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

le premier dure 2 minutes, tandis que le second - 4 secondes.

44
Ihor B.
select convert(varchar(max), field , 1) 
from table

Par using varchar(max) vous n'aurez pas à vous soucier de spécifier la taille (sorte de).

22
Charlie Affumigato

Ajouter une réponse qui montre un autre exemple de conversion de données binaires en une chaîne hexadécimale, et inversement.

je veux convertir la valeur timestamp la plus élevée en varchar:

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

Qui retourne:

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

Remarque: il est important que vous utilisiez CONVERT pour convertir varbinary -> varchar. L'utilisation de CAST ne fonctionnera pas:

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

traitera les données binaires comme des caractères plutôt que des valeurs hexadécimales, renvoyant une chaîne vide.

Inversez-le

Pour reconvertir la chaîne hexadécimale stockée en horodatage:

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

Remarque: Tout code est publié dans le domaine public. Aucune attribution requise.

8
Ian Boyd

Je suis tombé sur cette question en recherchant une solution à un problème similaire lors de l'impression de la valeur hexadécimale renvoyée par la fonction "hashbytes" dans SQL Server 2005.

Malheureusement, dans cette version de SQL Server, CONVERT ne semble pas fonctionner du tout, seul fn_varbintohexsubstring fait la bonne chose:

J'ai fait:

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)

Voici le résultat que j'ai obtenu dans 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

(il y a en fait un caractère non imprimable avant les 4Vx - je posterais une image, mais je n'ai pas encore assez de points).


Edit: Juste pour ajouter - sur SQL Server 2008 R2, le problème avec CONVERT est résolu avec la sortie suivante:

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
David Claughton
DECLARE @binvalue binary(4)
SET @binvalue = 0x61000000
PRINT @binvalue 
PRINT cast('a' AS binary(4))
PRINT cast(0x61 AS varchar)

Ne jetez pas.

La conversion convertit le binaire en texte par valeur sur le paramètre de classement correspondant pour la base de données spécifique.

[Commencer l'édition] Si vous avez besoin de la valeur imprimée dans une variable de chaîne, utilisez la fonction suggérée par 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 cette fonction n'est pas à votre disposition en raison des versions du serveur ou parce qu'elle a besoin d'autorisations spéciales, vous pouvez créer votre propre fonction.

Pour voir comment cette fonction a été implémentée dans l'édition SQL Server 2005 Express, vous pouvez exécuter:

sp_helptext 'fn_varbintohexsubstring'
2
Ricardo C