首先來講講SQL Server 中的位運算:
在SQL Server ,採用1,2,4,8,16.....等用數字標識的狀態字段可以進行累加,對存在的幾種狀態進行組合,從而可形成各種組合狀態
例如:一條記錄該字段原來的數字是,2,如我們想加上4,則可以用
update t_User set iFlag = iFlag | 4 where UserID = 1
(iFlag 爲該字段名)
例2:在加上4之後我們想去掉4怎麼辦呢,可以這樣實現
update t_User set iFlag = iFlag ^4 where UserID = 1
這樣就又把4從該記錄中去掉了.
如果我們想選擇所有爲2的記錄該怎麼做呢,可以這樣實現
select * from t_User where iFlag &2 = 2
SQL中的位運算不但可以取出各種值,而且我們可以對他對數據進行排序
舉例如下,新聞列表中的一個字段標識爲
1:置頂
2:不置頂
4:推薦
8:不推薦
該字段的值可以爲這4種狀態的組合,如果我們根據一定條件想把所有置頂的放在前面該如何做呢
select * from t_News order by iFlag & 1 desc
這樣我們就把所有置頂的貼子排在前面,當然這裏可以加上一定的Where 條件,在Where 裏也可可以加一定的位運算,
關於位運算可以查閱相應的SQL 幫助
下面來講一講C#中的枚舉位運算
這裏我們定義一個枚舉
[Flags]
enum UserFlag
{
a = 1,
b = 2,
c = 4,
d = 8,
e = 16,
f = 32
}
在代碼里加上如下處理
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string strSQL = "select * from v_User where iFlag & @iFlag = @iFlag";
//SqlParameter parm = new SqlParameter("@iFlag",SqlDbType.Int,4);
//parm.Value = UserFlag.a | UserFlag.b ;
SqlConnection con = new SqlConnection("server=.;database=Sinvan_TexDB;User Id=sa;pwd=123;");
SqlCommand comm = new SqlCommand(strSQL, con);
comm.Parameters.Add("@iFlag", SqlDbType.Int, 4).Value = UserFlag.a | UserFlag.b;
SqlDataAdapter adp = new SqlDataAdapter(comm);
DataTable dTable = new DataTable();
adp.Fill(dTable);
UserFlag userFlag = (UserFlag)Enum.Parse(typeof(UserFlag), dTable.Rows[0][11].ToString());
}
}
進行處理之後userFlag就是數據庫中存在的各種組合
我們同樣可對其進行一定的位運算處理
如我們想加上 UserFlag.c 可進行如下操作
userFlag = userFlag | Userflag.c
如想去掉UserFlag.c 可進行如下操作
userFlag = userFlag ^ UserFlag.c
如我們要判斷是該標識中是否存在c可進行如下操作
(userFlag & UserFlag.c) == UserFlag.c
是不是與SQL Server 中的操作類似,位運算不管什麼語言都是通用的,呵呵
可惜Access 不支持位運算,這也是一個遺憾吧,不過有高人寫過一模塊,一起提供,沒進行過測試,供大家參考
'Binary and operate
Public Function BitAnd(ByVal a As Long, ByVal b As Long) As Boolean
If (a <= 0 Or b <= 0) Then
BitAnd = False
Exit Function
End If
Dim b1() As Integer, b2() As Integer
ToBytes a, b1
ToBytes b, b2
Dim i As Integer
For i = 0 To 32
If b1(i) = b2(i) And b1(i) = 1 Then
BitAnd = True
Exit Function
End If
Next i
BitAnd = False
End Function
Private Sub ToBytes(ByVal v As Long, ByRef result() As Integer)
ReDim result(32) As Integer
Dim iLoc As Integer
DecToBin v, result(), iLoc
End Sub
Private Sub DecToBin(ByVal v As Long, ByRef result() As Integer, ByRef iLoc As Integer)
If v < 2 Then
result(iLoc) = v
Exit Sub
End If
Dim r As Integer
r = v Mod 2
result(iLoc) = r
iLoc = iLoc + 1
Dim m As Long
m = v / 2
DecToBin m, result, iLoc
End Sub