web-dev-qa-db-fra.com

Comment convertir les valeurs TIMESTAMP en VARCHAR dans T-SQL comme le fait SSMS?

J'essaie de convertir un champ TIMESTAMP d'une table en chaîne afin qu'il puisse être imprimé ou exécuté dans le cadre d'un SQL dynamique. SSMS est capable de le faire, il doit donc y avoir une méthode intégrée pour le faire. Cependant, je ne peux pas le faire fonctionner avec T-SQL.

Ce qui suit affiche correctement un résultat de table:

SELECT TOP 1 RowVersion FROM MyTable

Il montre 0x00000000288D17AE. Cependant, j'ai besoin que le résultat fasse partie d'une chaîne plus grande.

DECLARE @res VARCHAR(MAX) = (SELECT TOP 1 'test' + CONVERT(BINARY(8), RowVersion) FROM MyTable)
PRINT(@res)

Cela génère une erreur: The data types varchar and binary are incompatible in the add operator

DECLARE @res VARCHAR(MAX) = (SELECT TOP 1 'test' + CONVERT(VARCHAR(MAX), RowVersion) FROM MyTable)
PRINT(@res)

Cela se traduit par des caractères parasites: test (®

En fait, les espaces ne sont que des caractères nuls et terminent la chaîne dans le but d'exécuter du SQL dynamique à l'aide de EXEC().

DECLARE @sql VARCHAR(MAX) = 'SELECT TOP 1 ''test'' + CONVERT(VARCHAR(MAX), RowVersion) FROM MyTable'
EXEC (@sql)

Cela affiche simplement un résultat de table avec le mot "test". Tout ce qui suit le mot "test" dans le SQL dynamique est coupé, car la fonction CONVERT renvoie tout d'abord les caractères vides.

Évidemment, je veux que la chaîne résultante soit "test0x00000000288D17AE" ou même l’équivalent décimal, qui dans ce cas serait "test680335278".

Toutes les idées seraient grandement appréciées.

10
Neo

SELECT 'test' + CONVERT(NVARCHAR(MAX), CONVERT(BINARY(8), RowVersion), 1). Le truc est le 1 à la CONVERT comme style, selon le documentation . (Passez 2 pour omettre le 0x.)

19
Jeroen Mostert

Comme mentionné dans les commentaires, la fonction non documentée master.sys.fn_varbintohexstr convertira le binaire en chaîne de sorte que vous puissiez ensuite concaténer avec une autre valeur de chaîne:

DECLARE @binary BINARY(8)
SELECT @binary = CAST(1234567890 AS BINARY(8))

SELECT @binary AS BinaryValue, 
       LEFT(master.sys.fn_varbintohexstr(@binary),2) + UPPER(RIGHT(master.sys.fn_varbintohexstr(@binary),LEN(master.sys.fn_varbintohexstr(@binary))-2)) AS VarcharValue,
       'test' + LEFT(master.sys.fn_varbintohexstr(@binary),2) + UPPER(RIGHT(master.sys.fn_varbintohexstr(@binary),LEN(master.sys.fn_varbintohexstr(@binary))-2)) AS ConcatenatedVarcharValue

Je suis allé de l'avant et j'ai divisé les deux premiers caractères sans appliquer la fonction UPPER, afin de reproduire exactement le format affiché sous forme de valeur binaire.

Résultats:

/--------------------------------------------------------------------\
|     BinaryValue    |    VarcharValue    | ConcatenatedVarcharValue |
|--------------------+--------------------+--------------------------|
| 0x00000000499602D2 | 0x00000000499602D2 |  test0x00000000499602D2  |
\--------------------------------------------------------------------/
2
3N1GM4

Regardez ça:

SELECT 
substring(replace(replace(replace(replace(cast(CAST(GETDATE() AS datetime2) as 
varchar(50)),'-',''),' ',''),':',''),'.',''),1,18)
0
daniel