0

In SQL Server we can define a variable in hex representation as

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

Is it also possible to define them using binary like

DECLARE @bin INT = 0b1111; --I have tried this, it doesn't work

2 Answers 2

3

SQL Server doesn't have the functionality to read or store binary's out of the box, no. if you're storing a binary, you'd need to do so in a varchar. I.e. DECLARE @bin varchar(4) = '1111';.

Once you've stored the value as a varchar you'd the need to use a function to split the value out. Now, the largest number you can stored (as an integer) in SQL Server is 9223372036854775807, which is 63 digits long in binary (so we'll go for a varchar(64) to store the negative as well).

We can then create a table value function to convert the value from binary to an integer:

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

Finally, we can then Declare the variable and set the value:

DECLARE @Bin int;

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

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

Hope that helps.

I realise that real binary numbers don't have a negative, but this was just me short handing.

Edit: Although I realise that the Op said this isn't what they (seemed?) to be asking for, however, for completion I did a signed and unsigned version of the above:

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

This returns the values 15, -15, 143 and NULL (due to the 2) respectively.

Sign up to request clarification or add additional context in comments.

3 Comments

No I want to store it as a Number/Int, as you can see in question I am storing the values in an INT. But I wanted to write a query with binary representation so that it would have been more readable for us as we are using int like a set of flags. If there will be conversions necessary, then I have to go with decimal numbers themselves so that performance is not hampered.
@SaurabhHarwande - ideally, don't do that. The natural way to represent multiple facts in SQL is to store them as separate rows. Encoding them as "flags" may have some initial appeal but you'll come to discover that they complicate a great many queries and defeat any opportunities to optimize the database using the normal tools at our disposal.
Apologies, @SaurabhHarwande, but I'm not sure what you mean. In your initial post you seem to be looking for way for the binary to be converted to a integer. Is this not the case?
2

Here's the complete documentation for SQL Server Constants (their term for literals).

There is no syntax for providing input as binary 1s and 0s. They do have something referred to as a "binary constant" but that is simply the hexadecimal syntax that you're already using in your question.

(This also indicates that your first example is in fact as example of a binary constant and an implicit conversion to an int)

1 Comment

Ahh, I was seaching for a list of of valid datatypes. Thanks for the link. I may have to go with the hexadecimal respresentation itself I think.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.