Sql中的二进制数

时间:2017-12-27 11:10:54

标签: sql sql-server sql-server-2012

在SQL Server中,我们可以将十六进制表示形式的变量定义为

DECLARE @hex INT = 0xF; --This assigns value 15 to @hex

是否也可以使用像

这样的二进制文件来定义它们
DECLARE @bin INT = 0b1111; --I have tried this, it doesn't work

2 个答案:

答案 0 :(得分:2)

这是SQL Server Constants的完整文档(他们的文字术语)。

没有提供输入作为二进制1和0的语法。他们确实有一些被称为“binary constant”的东西,但这只是你在问题中使用的十六进制语法。

(这也表明你的第一个例子实际上是二进制常量的例子隐式转换为int

答案 1 :(得分:1)

SQL Server没有开箱即用的读取或存储二进制文件的功能,没有。如果您要存储二进制文件,则需要在varchar中执行此操作。即DECLARE @bin varchar(4) = '1111';

将值存储为varchar后,您需要使用函数将值拆分。现在,您可以在SQL Server中存储的最大数字(作为整数)为9223372036854775807,其长度为63位数(因此我们将使用varchar(64)存储负数)

然后我们可以创建一个表值函数来将值从二进制转换为整数:

CREATE FUNCTION dbo.BinaryToInt (@Binary varchar(64))
RETURNS TABLE WITH SCHEMABINDING AS
RETURN

    WITH C0 AS(SELECT 1 AS c UNION ALL SELECT 1),
         C1 AS(SELECT 1 AS c FROM C0 AS A CROSS JOIN C0 AS B),
         C2 AS(SELECT 1 AS c FROM C1 AS A CROSS JOIN C1 AS B),
         C3 AS(SELECT 1 AS c FROM C2 AS A CROSS JOIN C2 AS B),
    N AS (
        SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
        FROM C3)
    SELECT SUM(POWER(2, CASE B.V WHEN '-' THEN NULL ELSE N.I END -1) * B.V) * CASE WHEN MIN(B.V) = '-' THEN -1 ELSE 1 END AS IntegerValue
    FROM N
         CROSS APPLY (VALUES (SUBSTRING(REVERSE(@Binary), N.I, 1))) B(V)
    WHERE B.V <> '';
GO

最后,我们可以声明变量并设置值:

DECLARE @Bin int;

SELECT @bin = IntegerValue
FROM dbo.BinaryToInt ('1111');
SELECT @bin;

SELECT @bin = IntegerValue
FROM dbo.BinaryToInt ('-11101');
SELECT @Bin;

希望有所帮助。

我意识到真实二进制数字没有负数,但这只是我的简短处理。

编辑:虽然我意识到Op说这不是他们(似乎?)所要求的,但是,为了完成,我做了上面签名和未签名的版本: < / p>

CREATE FUNCTION dbo.UnSignedBinaryToInt (@Binary varchar(63))
RETURNS TABLE WITH SCHEMABINDING AS
RETURN

    WITH C0 AS(SELECT 1 AS c UNION ALL SELECT 1),
         C1 AS(SELECT 1 AS c FROM C0 AS A CROSS JOIN C0 AS B),
         C2 AS(SELECT 1 AS c FROM C1 AS A CROSS JOIN C1 AS B),
         C3 AS(SELECT 1 AS c FROM C2 AS A CROSS JOIN C2 AS B),
    N AS (
        SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
        FROM C3)
    SELECT SUM(POWER(2, N.I - 1) * B.V) AS IntegerValue
    FROM N
         CROSS APPLY (VALUES (SUBSTRING(REVERSE(@Binary), N.I, 1))) B(V)
    WHERE B.V <> ''
      AND @Binary NOT LIKE '%[^01]%' --Eliminate values that aren't binary;
GO

CREATE FUNCTION dbo.SignedBinaryToInt (@Binary varchar(64))
RETURNS TABLE WITH SCHEMABINDING AS
RETURN

    WITH C0 AS(SELECT 1 AS c UNION ALL SELECT 1),
         C1 AS(SELECT 1 AS c FROM C0 AS A CROSS JOIN C0 AS B),
         C2 AS(SELECT 1 AS c FROM C1 AS A CROSS JOIN C1 AS B),
         C3 AS(SELECT 1 AS c FROM C2 AS A CROSS JOIN C2 AS B),
    N AS (
        SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
        FROM C3),
    I AS (
        SELECT SUM(POWER(2, N.I - 1) * B.V) AS IntegerValue
        FROM N
             CROSS APPLY (VALUES (SUBSTRING(REVERSE(RIGHT(@Binary, LEN(@Binary)-1)), N.I, 1))) B(V)
        WHERE B.V <> ''
          AND @Binary NOT LIKE '%[^01]%' --Eliminate values that aren't binary
    )
    SELECT IntegerValue * CASE LEFT(@binary,1) WHEN 1 THEN -1 ELSE 1 END AS IntegerValue
    FROM I;

GO


SELECT IntegerValue
FROM dbo.UnSignedBinaryToInt ('00001111');
SELECT IntegerValue
FROM dbo.SignedBinaryToInt ('10001111');
SELECT IntegerValue
FROM dbo.UnSignedBinaryToInt ('10001111');
SELECT IntegerValue
FROM dbo.UnSignedBinaryToInt ('00201111');

GO

这将分别返回值15-15143NULL(由于2)。