在两个数据库系统之间工作,我需要将VARCHAR标识符转换为BIGINT。我的VARCHAR的格式总是“### - XXX-XXX - ###”,其中#是任意数字,X是任何字母数字字符(例如“103-AF7-GGB-005”)。两个###条目保证低于256,所以我想将它们中的每一个存储在BIGINT的单个字节中(分别是第一个和最后一个字节),每个其他6个字符分别存储为一个字节。
我在数据库之外实现了这个,它解决了我需要它的问题,但是现在我需要在t-sql中创建函数而我还没弄清楚如何做到这一点
提前感谢您的帮助!
答案 0 :(得分: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已签名。