PRB: Passing vtMissing as Output Parameter to ADO Function Gives Error (295692)



The information in this article applies to:

  • ActiveX Data Objects (ADO) 2.0
  • ActiveX Data Objects (ADO) 2.1
  • ActiveX Data Objects (ADO) 2.5
  • ActiveX Data Objects (ADO) 2.6
  • Microsoft Visual C++, 32-bit Editions 6.0
  • Microsoft Visual J++ 6.0

This article was previously published under Q295692

SYMPTOMS

When you pass a reference of vtMissing as an output parameter to an ActiveX Data Objects (ADO) function from Visual C++ or Visual J++, you may receive the following error:
The application is using arguments that are of the wrong type, are out of acceptable range, or are in conflict with one another.

CAUSE

Although vtMissing is a Variant value that is initialized to DISP_E_PARAMNOTFOUND, ADO does not treat this Variant value as optional, and actually modifies the value. Because vtMissing is a global variable, if you subsequently use vtMissing in another function, you will get unexpected results.

RESOLUTION

To resolve this problem, do not pass the reference of vtMissing to any ADO function as an output parameter. For example, if you have this line of code
conn->Execute( "Some SQL Statement", &vtMissing, adCmdText );
				
you can change it to the following:
conn->Execute( "Some SQL Statement", NULL, adCmdText );
				

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce Behavior

  1. Use the Visual C++ App Wizard to generate a Win32 Console application.
  2. Paste the following code in a .cpp file of the application:
    #undef EOF
    #import "c:\program files\common files\system\ado\msado15.dll" no_namespace
    #include <stdio.h>
    #include <conio.h>
    
    void main(void)
    {
    	CoInitialize(NULL);
    
    	_ConnectionPtr conn(__uuidof(Connection));
    	_RecordsetPtr rs(__uuidof(Recordset));
    
    
    	try
    	{
    		// Open connection to pubs database in a SQL Server server.
    		conn->Open( "Provider=SQLOLEDB;Server=Myserver;Database=Pubs;UID=sa;PWD=;", "", "", -1 );
    
    		// First open works fine.
    		rs->PutRefActiveConnection( conn );
    		rs->Open( "select * from authors", vtMissing, adOpenKeyset, adLockOptimistic, adCmdText );
    		rs->Close();
    		rs->PutRefActiveConnection( NULL );
    
    		// Pass vtMissing as an output parameter.
    		conn->Execute( "update authors set au_id=au_id where 1=0", &vtMissing, adCmdText );
    		// To remove the problem, comment the previous line and uncomment the following line.
    		//conn->Execute( "update authors set au_id=au_id where 1=0", NULL, adCmdText );
    
                    // When you open the same recordset again, it fails because ADO has modified vtMissing.
    		rs->PutRefActiveConnection( conn );
    		rs->Open( "select * from authors", vtMissing, adOpenKeyset, adLockOptimistic, adCmdText );
    		rs->Close();
    		rs->PutRefActiveConnection( NULL );
    
    	}
    	catch ( _com_error ex )
    	{
    
    
    		printf( "Com error %s (hr=0x%08x) thrown.\n", (char*) ex.Description(), ex.Error() );
    
    		for ( long i=0; i<conn->Errors->Count; i++ )
    		{
    			printf( "Error[%lu] %s.\n", i, (char*) conn->Errors->Item[i]->Description );
    		}
    	}
    
    	printf( "Test complete. Press any key to exit.\n" );
    	_getch();
    
    }
    					
  3. Modify the connection string to your own.
  4. Compile and then run the application. Note that the second Open call fails with the error message shown in the "Symptoms" section because vtMissing has been changed by ADO.

REFERENCES

For additional information, see the ADO documentation for Command::Execute and Connection::Execute.

Modification Type:MajorLast Reviewed:8/23/2001
Keywords:kbDSupport kbprb KB295692