Sql中的二进制数

问题描述 投票:0回答:2

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

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

是否也可以使用二进制来定义它们

DECLARE @bin INT = 0b1111; --I have tried this, it doesn't work
sql sql-server sql-server-2012
2个回答
2
投票

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

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

(这也表明您的第一个示例实际上是二进制常量的示例,并且隐式转换为int


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说这不是他们(似乎?)所要求的,但是,为了完成,我做了上面签名和未签名的版本:

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)。

© www.soinside.com 2019 - 2024. All rights reserved.