Microsoft Knowledge Base Email Alertz

(194206) - The Microsoft ODBC Driver for Access and the Microsoft OLE DB Provider for Jet do not provide support for bit-wise operations in SQL statements. Attempts to use AND, OR, and XOR with numeric fields in a SQL statement return the result of a logical...

Search KbAlertz

Advanced Search

Receive Microsoft Knowledge Base articles by E-Mail?

Every night we scan the Microsoft Knowledge Base. If technologies you're interested in are updated, we'll send you an e-mail. You only get one e-mail a day, and only when new articles are added.

Click here to create a
FREE account
Already have an account?
[Click here to Login]











Microsoft Knowledge Base Article

This article contents is Microsoft Copyrighted material.
©2005-©2007 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks

Article ID: 194206 - Last Review: December 9, 2004 - Revision: 3.1

FIX: Jet drivers do not support bitwise operators

This article was previously published under Q194206

SYMPTOMS

The Microsoft ODBC Driver for Access and the Microsoft OLE DB Provider for Jet do not provide support for bitwise operations in SQL statements. Attempts to use AND, OR, and XOR with numeric fields in a SQL statement return the result of a logical operation (true or false).

CAUSE

The Microsoft Jet database engine does not support bitwise operations in SQL.

RESOLUTION

Bitwise operations must be replaced with the equivalent mathematical expressions or performed on the data outside of a SQL statement (performed in Visual Basic for Applications code for example).

STATUS

This behavior is by design.

MORE INFORMATION

You can test for a single bit set in a long integer or integer field using the following algorithm:
( <value> \ (2^<bit>) ) mod 2
This expression will return 1 if the <bit> is set and 0 if <bit> is not set. <bit> is numbered from 0 to 30 inclusive where <bit>=0 is the first bit. <bit> values greater than 30 will not work with this algorithm because Jet uses unsigned long integer values and 2^31 is one larger than the largest unsigned long integer value and thus will cause numeric overflow when the division is evaluated.

Note that the \ operator and not the / operator is used. The \ operator is used for integer division. The / operator is used for floating point division and will cause unexpected results when used with this algorithm.

You can check <bit> 31 for a long integer using the following algorithm:
iif( <value> < 0, 1, 0 )
This works because an unsigned long integer that is less than zero means the highest order bit (bit 31 for a long) is set.

Suppose you have a table named Test and a long integer field named TestFlags. You can use the following SQL statements to test to see if the bit 11 is set in the TestFlags field
SELECT * FROM Test WHERE ([TestFlags]\2^11) mod 2 = 1
				
or replace 2^11 with 2048 to save some query calculation time:
SELECT * FROM Test WHERE ([TestFlags]\2048) mod 2 = 1
				
You can use the following SQL to test for bit 31
SELECT * FROM Test WHERE iif( [TestFlags] < 0, 1 ,0 ) = 1
				
but this SQL statement would be a much more efficient test for bit 31:
SELECT * FROM Test WHERE [TestFlags] < 0
				
Note that you can also create calculated columns in SQL to display the results of one or more bit checks:
SELECT ([TestFlags]\2^11) mod 2 AS Bit11Set FROM Test
				
You can run the following ADO code to verify that this algorithm works correctly over various ranges and with various bit flags. Note the test requires a blank Microsoft Access database named C:\Db1.mdb and a reference to Microsoft ActiveX Data Objects.
   ' START SAMPLE CODE
   Sub VerifyBitTest()
   Dim i As Long, min As Long, max As Long, bit As Long
   Dim conn As New ADODB.Connection
   Dim rs As New ADODB.recordset

      conn.Open "DRIVER=Microsoft Access Driver (*.mdb);" & _
      "MAXBUFFERSIZE=128;DBQ=c:\db1.mdb"
      On Error Resume Next
         conn.Execute "DROP TABLE Test"
      On Error GoTo 0
      conn.Execute "CREATE TABLE Test (TestFlags LONG)"
      conn.Execute "INSERT INTO Test (TestFlags) VALUES (0)"
      min = 2 ^ 0: max = 2 ^ 30: bit = 11
      For i = min To max ' This could take a while.
         rs.Open "SELECT (" & i & "\2^" & bit & _
                 ") mod 2 AS BitSet FROM Test", conn
         If rs!BitSet <> IIf((i And (2 ^ bit)) > 0, 1, 0) Then
            MsgBox "Bit Test Failure!"
            Exit Sub
         End If
         rs.Close
         DoEvents
         If i Mod 100 = 0 Then Debug.Print "Verified " & i & " of " & max
      Next i

   End Sub
   ' END SAMPLE CODE
				

APPLIES TO
  • Microsoft Open Database Connectivity Driver for Access 1.0
  • Microsoft Open Database Connectivity Driver for Access 2.0
  • Microsoft Open Database Connectivity Driver for Access 3.0
  • Microsoft Open Database Connectivity Driver for Access 3.5
  • Microsoft Open Database Connectivity Driver for Access 3.6
  • Microsoft OLE DB Provider for Jet 3.51
  • Microsoft Data Access Components 2.1 Service Pack 2
  • Microsoft Data Access Components 2.5
Keywords: 
kbbug kbfix KB194206
       

Community Feedback System

Very often, it takes hours to solve a problem. Very often, you've looked high and low, and have tried a lot of solutions. When you finally found it, chances are, it was because someone else helped you. Here's your chance to give back. Use our community feedback tool to let others know what worked for you and what didn't.

Please also understand that the community feedback system is not warranted to be correct, it's simply a system that we've built to let people try and help each other. If something in a feedback response doesn't make sense to you, or you're not comfortable making changes that the feedback talks about (like registry edits), please consult a professional.

Thank you for using kbAlertz.com Feedback System.

-- Scott Cate