Преобразование/объединение отдельных байтов из VARCHAR в BIGINT с использованием T-SQL

Работая между двумя системами баз данных, мне нужно преобразовать идентификатор VARCHAR в BIGINT. Мой VARCHAR всегда имеет форму «###-XXX-XXX-###», где # — любая цифра, а X — любой буквенно-цифровой символ (например, «103-AF7-GGB-005»). Две записи ### гарантированно будут ниже 256, поэтому я хочу сохранить каждую из них в одном байте BIGINT (первый и последний байты соответственно), при этом каждый из 6 других символов хранится как байт каждый.

Я реализовал это вне базы данных, и это решает проблему, в которой я нуждался, но теперь мне нужно создать функцию в t-sql, и я не смог понять, как это сделать.

Заранее спасибо за помощь!


person Belizzle    schedule 25.04.2012    source источник


Ответы (1)


Вы можете сделать это:

DECLARE @inp VARCHAR(100) = '223-ABC-DEF-234'
    , @BITS BIGINT;

SELECT @BITS = 
        CASE 
            WHEN CONVERT(BIGINT, LEFT(@inp, 3)) > 127
                THEN (CONVERT(BIGINT, LEFT(@inp, 3))-128) * POWER(CONVERT(BIGINT, 2), 56) 
                     -9223372036854775808
            ELSE CONVERT(BIGINT, LEFT(@inp, 3)) * POWER(CONVERT(BIGINT, 2), 56)
        END
    + CONVERT(BIGINT, ASCII(substring(@inp, 5, 1))) * POWER(CONVERT(BIGINT, 2), 48)
    + CONVERT(BIGINT, ASCII(substring(@inp, 6, 1))) * POWER(CONVERT(BIGINT, 2), 40)
    + CONVERT(BIGINT, ASCII(substring(@inp, 7, 1))) * POWER(CONVERT(BIGINT, 2), 32)
    + CONVERT(BIGINT, ASCII(substring(@inp, 9, 1))) * POWER(CONVERT(BIGINT, 2), 24)
    + CONVERT(BIGINT, ASCII(substring(@inp, 10, 1))) * POWER(CONVERT(BIGINT, 2), 16)
    + CONVERT(BIGINT, ASCII(substring(@inp, 11, 1))) * POWER(CONVERT(BIGINT, 2), 8)
    + CONVERT(BIGINT, RIGHT(@INP, 3));

select CONVERT(binary(8), @bits);
-- Returns 0xDF414243444546EA

SELECT CONVERT(VARCHAR, CONVERT(INT, 0XDF))
    + '-' + CHAR(0X41)
    + CHAR(0X42)
    + CHAR(0X43)
    + '-' + CHAR(0X44)
    + CHAR(0X45)
    + CHAR(0X46)
    + '-' + CONVERT(VARCHAR, CONVERT(INT, 0XEA));

-- Returns 223-ABC-DEF-234: our original string

Большое вычитание состоит в том, чтобы перевернуть бит знака. Вы используете все 64 бита, если первое число больше 127. Простое умножение на 2 ^ 56 приведет к переполнению типа данных, поскольку BIGINT подписан.

person JAQFrost    schedule 25.04.2012
comment
Это именно то, что мне нужно было сделать. Спасибо за помощь! - person Belizzle; 26.04.2012