FIX: Getting Select Distinct To Work Under ADO with SQL Server

ID: Q181479


The information in this article applies to:


SYMPTOMS

Under certain conditions with ActiveX Data Objects (ADO), SELECT DISTINCT in your SQL statement will not provide distinct records.

Any of the following situations produces incorrect results with SQL Server:

This happens when you use either the Recordset.Open method or when the recordset is obtained from a command object by setting the recordset equal to the return value of Command.Execute.


CAUSE

The reason this does not work with adUseClient is that ADO uses SQL Server's FOR BROWSE option on the SQL statement to get extended metadata in order to process updates. The use of this option causes SQL version 6.5 to ignore the DISTINCT keyword.


RESOLUTION

Here are the two possible techniques you can use to get SELECT DISTINCT to work as expected:

The Steps to Reproduce Behavior section demonstrates the workarounds for both the Open and the Command methods.


STATUS

This bug was corrected in ActiveX Data Objects, version 2.0.


MORE INFORMATION

Steps to Reproduce Behavior

  1. Create a standard .exe project, and from the Project menu, choose References, then select Microsoft ActiveX Data Objects 1.5 Library.


  2. Paste the following code in the Declaration section of the form:



  3. 
    
    Option Explicit
    
       Dim conn As New Connection
       'Dim com As New Command  'Uncomment to make DISTINCT work.
       Dim rs As New Recordset
    
     
       Private Sub Command1_Click()
    
         conn.open "mymachine", "sa", ""
         conn.cursorlocation = adUseClient  'Change to aduseServer.
         'com.ActiveConnection = conn  'Uncomment to make DISTINCT work.
    
         rs.open "select distinct state from authors", conn, _
             adOpenKeyset, adLockOptimistic
            MsgBox rs.RecordCount
       End Sub
    
       Private Sub Command2_Click()
         Dim counter As Integer
         counter = 0
            conn.Open "dsn=mymachine;id=sa;pwd=;"
            com.ActiveConnection = conn
            conn.CursorLocation = adUseClient   'Comment this
            'conn.CursorLocation = adUseServer  'and uncomment this.
            com.CommandText = "select distinct state from authors"
            com.CommandType = adCmdText
            rs.CursorType = adOpenKeyset
            'cursortype will be adopenforwardonly with adUseServer.
            Set rs = com.Execute
            While Not rs.EOF
              Debug.Print rs!State
              counter = counter + 1
              rs.MoveNext
            Wend
            Debug.Print "--------------------"
            MsgBox counter  'recordcount return -1 with adUseServer
       End Sub 
  4. Run the code and click Command1. Note the number of records returned. Change adUseClient to adUseServer in the CursorLocation. Run the code again and fewer records are returned if there are duplicate states.


  5. Change aduseServer back to adUseClient. Uncomment the Dim of the command object and the code in Command1. Run the code again. You receive the correct number of records using this technique also.


  6. NOTE: If you set the recordset properties ahead of time and use the syntax Rs.open com the recordcount returned will be incorrect. However, to get the correct recordcount using the Rs.Open method you must use a command object and set its active connection.

  7. Run the code again and click Command2. Note the counter. Comment the CursorLocation for adUseClient and uncomment the adUseServer CursorLocation. Run the code and note the counter again.



REFERENCES

For additional information, please see the following article in the Microsoft Knowledge Base:

Q172115 BUG: DISTINCT with NO_BROWSETABLE Returns Duplicate Rows

Additional query words: kbdse kbcrossref


Keywords          : kbcode kbADO100 kbADO150 
Version           : WINDOWS:1.0,1.5
Platform          : WINDOWS 
Issue type        : kbbug 

Last Reviewed: February 25, 1999