我有一个表有一个名为Permission(binary(8))的列,其每一位代表一个特定的操作权限。在Silverlight客户端中,我使用BitArrary和const整数来管理权限,并且顺利进行。客户端代码如下:
public class StaffBase : INotifyPropertyChanged
{
public const int
OPERATION_A = 0,
OPERATION_B = 1,
// ...
// OPERATION_I=i,
// ...
OPERATION_63 = 63;
BitArray permission = null;
public BitArray Permission
{
get { return permission; }
set
{
if (permission != value)
{
permission = value;
OnPropertyChanged("Permission");
}
}
}
bool TestPermission(int permissionName)
{
return permission != null && permission[permissionName];
}
/*
Other code segments
*/
}
现在的问题是我必须在存储过程中测试权限,不幸的是我对SQL有点新手。我在客户端设置了2 ^ 10的权限,如下所示:
permission[10]=true;
我想我会在数据库的Permission列中得到1024的值。但实际上列值为0x0004000000000000。看来,byte []的不同存储策略分别由SQL和.NET采用。现在我正在寻找一种方法来检测Permission列的cetern位。我试图使用这样的条款:
Permission & power(2,i) > 0
效果不对。还有一个蚂蚁问题:如果我想测试第63位,则功率(2,63)会溢出。现在我希望一些sql master能给我一个指导。
答案 0 :(得分:1)
BitArray按顺序写入各个位,就像您正在阅读一样,即。第一位是第一个字节的第7位,第8位是第一个字节的第0位,第9位是第二个字节的第7位等。所以最小的解决方案是你必须反转位数(而不是power(2, i)
,请power(2, 64 - i)
。当然,正如您所观察到的,这是非常有限的。一个可以达到64位的选项是简单地使用更大的数据类型 - bigint
。但是,对于任何大于64位的内容,您都会回到原来的位置。
对于更通用的解决方案,您希望基于每个字节使用二进制字段。您可以使用substring
功能。
select
substring(binaryValue, ceiling(cast(@bit as decimal) / 8), 1)
& power(2, @bit % 8);
如果未设置指定位,则为零,如果为,则为非零值。
这里的关键是字符串函数实际上也适用于二进制/图像,所以你可以这样做。只使用substring :)
随意访问任何字节