1

在两个数据库系统之间工作,我需要将 VARCHAR 标识符转换为 BIGINT。我的 VARCHAR 始终采用“###-XXX-XXX-###”的形式,其中 # 是任何数字,X 是任何字母数字字符(例如“103-AF7-GGB-005”)。这两个### 条目保证低于 256,因此我想将它们中的每一个存储在 BIGINT 的单个字节中(分别是第一个和最后一个字节),而其他 6 个字符中的每一个都存储为一个字节。

我已经在数据库之外实现了这个,它解决了我需要它的问题,但现在我需要在 t-sql 中创建函数,但我无法弄清楚如何做到这一点。

在此先感谢您的帮助!

4

1 回答 1

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

最大的减法是翻转符号位。如果第一个数字超过 127,则使用所有 64 位。仅乘以 2^56 就会溢出数据类型,因为 BIGINT 是有符号的。

于 2012-04-25T22:52:00.097 回答