sql >> Databasteknik >  >> RDS >> Sqlserver

Hur kan jag göra AND BIT OPERATOR mellan två varbinära fält i SQL

Efter en lång diskussion har jag äntligen kommit fram till vilken indata du har. Du har en varbinary(128) som är konstruerad från en binär sträng (som '1000010010101... ') som är 1024 tecken lång. SQL Server tillhandahåller inte en färdig funktion som gör en sådan konvertering. Jag har byggt en så att jag kan testa. Följande funktion gör en sådan konvertering:

CREATE FUNCTION dbo.binStringToBinary(@inputString VARCHAR(1024)) RETURNS VARBINARY(128) AS
BEGIN
    DECLARE @inputBinary VARBINARY(128) = convert(varbinary, '', 2)
    DECLARE @octet int = 1
    DECLARE @len int
    SET @len = Len(@inputString)
    while @octet < @len
    BEGIN
        DECLARE @i int = 0
        DECLARE @Output int = 0
        WHILE(@i < 7) BEGIN
            SET @Output = @Output + POWER(CAST(SUBSTRING(@inputString, @octet + @i, 1) AS int) * 2, 7 - @i)
            SET @i = @i + 1
        END
        SET @Output = @Output + CAST(SUBSTRING(@inputString, @octet + @i, 1) AS int)
        select @inputBinary = @inputBinary + convert(varbinary(1), @Output)
        -- PRINT substring(@inputString, @octet, 8) + ' ' + STR(@Output, 3, 0) + ' ' + convert(varchar(1024), @inputBinary, 2)
        SET @octet = @octet + 8
    END
    RETURN @inputBinary
END

Jag har sedan skrivit en funktion som letar efter lite med hjälp av varbinary(128) som indata:

CREATE FUNCTION dbo.[DoBitsMatchFromBinary](@bitToCheck INT,@inputBinary VARBINARY(1024))
RETURNS BIT
AS
BEGIN
    IF @bitToCheck < 1 OR @bitToCheck > 1024
        RETURN 0

    DECLARE @byte int = (@bitToCheck - 1) / 8
    DECLARE @bit int = @bitToCheck - @byte * 8
    DECLARE @bytemask int = POWER(2, [email protected])
    SET @byte = @byte + 1

    RETURN CASE WHEN CONVERT(int, CONVERT(binary(1), SUBSTRING(@inputBinary, @byte, 1), 2)) & @bytemask = @bytemask THEN 1 ELSE 0 END
END

Som en bonus har jag även inkluderat här en funktion som gör bitkontrollen från en binär ingångssträng(1024):

CREATE FUNCTION dbo.[DoBitsMatchFromBinString](@bitToCheck INT,@inputString VARCHAR(1024))
RETURNS BIT
AS
BEGIN
    IF @bitToCheck < 1 OR @bitToCheck > 1024
        RETURN 0

    RETURN CASE WHEN SUBSTRING(@inputString, @bitToCheck, 1) = '1' THEN 1 ELSE 0 END
END

Kontrollera SQL-fiolen som visar deras användning.

DECLARE @inputBinary VARBINARY(128)
select @inputBinary = dbo.binStringToBinary('1010001000101111010111010100001101000100010111101011101010000101101000100010111101011101010000110100010001011110101110101000010110100010001011110101110101000011010001000101111010111010100001011010001000101111010111010100001101000100010111101011101010000101101000100010111101011101010000110100010001011110101110101000010110100010001011110101110101000011010001000101111010111010100001011010001000101111010111010100001101000100010111101011101010000101101000100010111101011101010000110100010001011110101110101000010110100010001011110101110101000011010001000101111010111010100001011010001000101111010111010100001101000100010111101011101010000101101000100010111101011101010000110100010001011110101110101000010110100010001011110101110101000011010001000101111010111010100001011010001000101111010111010100001101000100010111101011101010000101101000100010111101011101010000110100010001011110101110101000010110100010001011110101110101000011010001000101111010111010100001011010001000101111010111010100001101000100010111101011101010000101')
select dbo.[DoBitsMatchFromBinary](1, @inputBinary) bit1,
       dbo.[DoBitsMatchFromBinary](2, @inputBinary) bit2,
       dbo.[DoBitsMatchFromBinary](3, @inputBinary) bit3,
       dbo.[DoBitsMatchFromBinary](4, @inputBinary) bit4,
       dbo.[DoBitsMatchFromBinary](5, @inputBinary) bit5,
       dbo.[DoBitsMatchFromBinary](6, @inputBinary) bit6,
       dbo.[DoBitsMatchFromBinary](7, @inputBinary) bit7,
       dbo.[DoBitsMatchFromBinary](8, @inputBinary) bit8,
       dbo.[DoBitsMatchFromBinary](1017, @inputBinary) bit1017,
       dbo.[DoBitsMatchFromBinary](1018, @inputBinary) bit1018,
       dbo.[DoBitsMatchFromBinary](1019, @inputBinary) bit1019,
       dbo.[DoBitsMatchFromBinary](1020, @inputBinary) bit1020,
       dbo.[DoBitsMatchFromBinary](1021, @inputBinary) bit1021,
       dbo.[DoBitsMatchFromBinary](1022, @inputBinary) bit1022,
       dbo.[DoBitsMatchFromBinary](1023, @inputBinary) bit1023,
       dbo.[DoBitsMatchFromBinary](1024, @inputBinary) bit1024


| bit1 |  bit2 | bit3 |  bit4 |  bit5 |  bit6 | bit7 |  bit8 | bit1017 | bit1018 | bit1019 | bit1020 | bit1021 | bit1022 | bit1023 | bit1024 |
|------|-------|------|-------|-------|-------|------|-------|---------|---------|---------|---------|---------|---------|---------|---------|
| true | false | true | false | false | false | true | false |    true |   false |   false |   false |   false |    true |   false |    true |


  1. körde en oracle-lagrad procedur från SQL-servern med hjälp av den öppna frågefunktionen

  2. Lösning i mysql för partiellt index eller filtrerat index?

  3. Guide för att designa databas för anställdas ledningssystem i MySQL

  4. Hur man kontrollerar inaktuell statistik