CONTEXT INFO() и конвертировать
в попытке построить пример кода этой вопрос, я столкнулся с проблемой с CONTEXT_INFO()
.
то, что я делаю, это преобразование int в varbinary (128), чтобы я мог передать это SET CONTEXT_INFO
. Я могу преобразовать varbinary обратно в int, прежде чем я сделаю набор, но после того, как я установил, а затем получил, преобразование всегда возвращает ноль, даже если значение varbinary явно не равно нулю.
Binary не моя сильная сторона, поэтому я, вероятно, что-то упускаю простой.
код
SET NOCOUNT ON
USE tempdb
GO
DECLARE @number int
DECLARE @ContextInfo varbinary(128)
SET @number = 16777216
SET @ContextInfo = CONVERT(varbinary(128), @number)
SELECT @number AS [@number]
SELECT @ContextInfo AS [@ContextInfo]
SELECT CONVERT(int, @ContextInfo) AS [CONVERT(int, @ContextInfo)]
SET CONTEXT_INFO @ContextInfo
GO
SELECT CONTEXT_INFO() AS [CONTEXT_INFO()]
SELECT CONVERT(int, CONTEXT_INFO()) AS [CONVERT(int, CONTEXT_INFO()) (Zero)]
GO
DECLARE @ContextInfo varbinary(128)
SET @ContextInfo = CONTEXT_INFO()
SELECT @ContextInfo AS [@ContextInfo]
SELECT CONVERT(int, @ContextInfo) AS [CONVERT(int, @ContextInfo) (Zero)]
GO
результат
@number
-----------
16777216
@ContextInfo
-----------------------------------
0x01000000
CONVERT(int, @ContextInfo)
--------------------------
16777216
CONTEXT_INFO()
-----------------------------------
0x0100000000000000[... more zeroes]
CONVERT(int, CONTEXT_INFO()) (Zero)
-----------------------------------
0
@ContextInfo
-----------------------------------
0x0100000000000000[... more zeroes]
CONVERT(int, @ContextInfo) (Zero)
-----------------------------------
0
пытаюсь ли я преобразовать его непосредственно из CONTEXT_INFO()
или писать CONTEXT_INFO()
переменной, результат CONVERT
равна нулю.
Edit: исправлен текст ссылки
Пример Преобразования
в этом примере показано, как int, преобразованный в varbinary(128), преобразуется обратно без проблем, но CONTEXT_INFO() не выполняет преобразование.
(это для текущих разговор с Andomar.)
тест
DECLARE @int int
DECLARE @varBin128 varbinary(128)
SET @int = 1
SET @varBin128 = CONVERT(varbinary(128), @int)
SET CONTEXT_INFO @varBin128
SELECT CONVERT(int, @varBin128) AS [Convert @varBin128)]
SELECT CONVERT(int, CONTEXT_INFO()) AS [Convert once]
SELECT CONVERT(int, CONVERT(varbinary(4), CONTEXT_INFO())) AS [Convert twice]
результаты
Convert @varBin128)
-------------------
1
Convert once
------------
0
Convert twice
-------------
1
3 ответов
varbinary (128) - это 128-байтовый блок памяти. Int - это 4-байтовый блок памяти. Таким образом, вы можете восстановить int следующим образом:
select convert(int,convert(varbinary(4),CONTEXT_INFO()))
var в varbinary означает, что фактическая длина изменяется, число в скобках просто указывает максимальный размер. Таким образом, эта инструкция SELECT отображает 4-байтовый varbinary:
select convert(varbinary(128), 1)
но когда вы бросаете CONTEXT_INFO () в varbinary (128), вы действительно получаете 128-байтовый varbinary. Этот пример хороший демонстрация:
set context_info 1
select convert(int,convert(varbinary(5),context_info()))
это будет печатать 256; последние 3 байта целого числа 1 с добавлением 0 байт.
вот как я бы это сделал. подстрока работает с двоичным кодом, поэтому нам не нужны промежуточные преобразования (в varbinary (4)):
SET CONTEXT_INFO 12345
SELECT
CONTEXT_INFO(),
CAST(CONTEXT_INFO() AS int), --zero
/*CAST(LEFT(CONTEXT_INFO(), 4) AS int),*/ --fails
CAST(SUBSTRING(CONTEXT_INFO(), 1, 4) AS int) --works
Примечание: левый не работает хорошо с двоичным кодом и терпит неудачу с ошибкой преобразования
ответ, по-видимому, представляет собой комбинацию рекомендаций от Andomar и gbn и рекомендации одного из моих коллег.
Если вы используете binary(128) вместо varbinary (128), все проще.
запрос
--<< ====================================================
--<< varbinary
--<< ====================================================
DECLARE @varbin128 varbinary(128)
SET @varbin128 = CONVERT(varbinary(128), 12345)
SET CONTEXT_INFO @varbin128
SELECT
@varbin128 AS [@varbin128],
CONTEXT_INFO() AS [CONTEXT_INFO()],
CONVERT(int, @varbin128) AS [Convert (@varbin128)],
CONVERT(int, CONTEXT_INFO()) AS [Convert (CONTEXT_INFO())],
CONVERT(int, CONVERT(varbinary(4), CONTEXT_INFO())) AS [Convert(x2) (CONTEXT_INFO())]
--<< ====================================================
--<< binary
--<< ====================================================
DECLARE @bin128 binary(128)
SET @bin128 = CONVERT(binary(128), 12345)
SET CONTEXT_INFO @bin128
SELECT
@bin128 AS [@bin128],
CONTEXT_INFO() AS [CONTEXT_INFO()],
CONVERT(int, @bin128) AS [Convert (@bin128)],
CONVERT(int, CONTEXT_INFO()) AS [Convert (CONTEXT_INFO())],
CONVERT(int, CONVERT(binary(4), CONTEXT_INFO())) AS [Convert(x2) (CONTEXT_INFO())]
результаты
@varbin128 CONTEXT_INFO() Convert (@varbin128) Convert (CONTEXT_INFO()) Convert(x2) (CONTEXT_INFO())
---------- ---------------- -------------------- ------------------------ ----------------------------
0x00003039 0x00003039000... 12345 0 12345
@bin128 CONTEXT_INFO() Convert (@bin128) Convert (CONTEXT_INFO()) Convert(x2) (CONTEXT_INFO())
--------------- --------------- ----------------- ------------------------ ----------------------------
0x000...0003039 0x000...0003039 12345 12345 0
Так, are способы заставить преобразование работать, если вы передаете значение varbinary (128), но для этого требуется двойное преобразование. Если вы передаете двоичное (128) значение, оно требует только один новообращенный.