我正在尝试修复数据,其中一个列在int列中存储了许多位标志。
所发生的事情是沿着这条线,设置了一个不正确的标志(6),所以我需要准备一个脚本来修复受影响的记录。
我尝试执行一些查询来提取似乎错误的数据,但这是基于假设的,我想知道是否有更明智的方法。
一些事实:
8,但是使用了6。考虑到6是无效的,基于这个事实,我能做些什么聪明的事情来提取这些记录吗?
发布于 2014-01-15 19:56:02
在这种情况下,我假设您在这里讨论的是bit masking。
有了这个假设,我认为您将无法仅仅查询数据以获得修复。bit masking的工作方式是将所有位的值相加(即将二进制转换为int),因此下面的掩码:1001将存储为9
如果您使用6而不是8,它将是相同的,如果4和2位都是设置的。因此,您的查询将返回4位和2位打开的所有有效记录。
使用相同的示例,如果您不小心使用了6而不是8,那么1001变成7,但是您如何将其与0111区别开来,后者将被正确地伪装为7?
发布于 2014-01-15 20:42:40
注意,位31在处理32位有符号值时可能会出现问题.否则:
-- Check each bit in an integer.
declare @Sample as Int = 6;
with Bits as (
select Cast( 1 as BigInt ) as BitMask, 0 as BitPosition
union all
select Bitmask * 2, BitPosition + 1
from Bits
where BitPosition < 31 )
select BitPosition, BitMask,
case when Cast( @Sample as BigInt ) & BitMask <> 0 then 'Set' else 'Clear' end as State
from Bits;
-- Play with some sample data in a table.
declare @Samples as Table ( SampleId Int Identity, Number Int );
insert into @Samples ( Number ) values ( 0 ), ( 1 ), ( 2 ), ( 3 ), ( 30 ), ( 65 ), ( 16385 );
select * from @Samples;
-- Clear bit 6 in each row.
update @Samples
set Number &= 2147483647 - Power( 2, 6 );
select * from @Samples;
-- Set bit 6 in each row.
update @Samples
set Number |= Power( 2, 6 );
select * from @Samples;
-- Clear bit 6 in each row again.
update @Samples
set Number &= 2147483647 - Power( 2, 6 );
select * from @Samples;发布于 2014-01-15 20:03:02
您可以使用T-SQL位运算符实现它,如下所示:
set nocount on;
declare @test table (id int identity primary key, bits int);
insert into @test values(63);
insert into @test values(1);
select id, cast(bits as binary(4)) as 'bits'
from @test;
update @test
set bits = (bits & 8388575) | 128
where (bits & 32) <> 0;
select id, cast(bits as binary(4)) as 'bits'
from @test;
/*
Outputs
id bits
----------- ----------
1 0x0000003F
2 0x00000001
id bits
----------- ----------
1 0x0000009F
2 0x00000001
*/https://stackoverflow.com/questions/21146871
复制相似问题