動的SQLの一部として印刷または実行できるように、テーブルのTIMESTAMPフィールドを文字列に変換しようとしています。 SSMSはそれを行うことができるので、それを行うには組み込みのメソッドが必要です。ただし、T-SQLを使用して動作させることはできません。
以下はテーブルの結果を正しく表示します:
_SELECT TOP 1 RowVersion FROM MyTable
_
_0x00000000288D17AE
_と表示されます。ただし、結果をより大きな文字列の一部にする必要があります。
_DECLARE @res VARCHAR(MAX) = (SELECT TOP 1 'test' + CONVERT(BINARY(8), RowVersion) FROM MyTable)
PRINT(@res)
_
これによりエラーが発生します:_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)
_
これにより、文字化けが発生します:_test (®
_
実際、スペースは単なるヌル文字であり、EXEC()
を使用して動的SQLを実行するために文字列を終了します。
_DECLARE @sql VARCHAR(MAX) = 'SELECT TOP 1 ''test'' + CONVERT(VARCHAR(MAX), RowVersion) FROM MyTable'
EXEC (@sql)
_
これは、Wordの「テスト」を含むテーブル結果を表示するだけです。 CONVERT
関数が最初に終端のヌル文字を返すため、動的SQLの「テスト」以降はすべて切断されます。
明らかに、結果の文字列にしたいのは「test0x00000000288D17AE」または同等の10進数でさえあり、この場合は「test680335278」になります。
どんなアイデアでも大歓迎です。
SELECT 'test' + CONVERT(NVARCHAR(MAX), CONVERT(BINARY(8), RowVersion), 1)
。トリックは、スタイルとして1
をCONVERT
に、 ドキュメント ごとに指定します。 (2
を省略するには、0x
を渡します。)
コメントで述べたように、文書化されていない関数master.sys.fn_varbintohexstr
は、バイナリを文字列に変換して、他の文字列値と連結できるようにします。
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
先に進み、最初の2文字を分割し、UPPER
関数をそれらに適用せず、バイナリ値のときに表示される形式を正確に再現しました。
結果:
/--------------------------------------------------------------------\
| BinaryValue | VarcharValue | ConcatenatedVarcharValue |
|--------------------+--------------------+--------------------------|
| 0x00000000499602D2 | 0x00000000499602D2 | test0x00000000499602D2 |
\--------------------------------------------------------------------/
これを見てください:
SELECT
substring(replace(replace(replace(replace(cast(CAST(GETDATE() AS datetime2) as
varchar(50)),'-',''),' ',''),':',''),'.',''),1,18)