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) значение, оно требует только один новообращенный.