1

2 つのデータベース システム間で作業しているため、VARCHAR 識別子を BIGINT に変換する必要があります。VARCHAR の形式は常に "###-XXX-XXX-###" で、# は任意の数字、X は任意の英数字 (例: "103-AF7-GGB-005") です。2 つの ### エントリは 256 未満であることが保証されているため、それぞれを BIGINT の 1 バイト (それぞれ最初と最後のバイト) に格納し、他の 6 文字はそれぞれ 1 バイトとして格納します。

これをデータベースの外に実装しましたが、必要な問題は解決しましたが、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 ビットすべてを使用しています。BIGINT は符号付きであるため、2^56 を掛けるだけでデータ型がオーバーフローします。

于 2012-04-25T22:52:00.097 に答える