Microsoft KB Archive/295692

= PRB: Passing vtMissing as Output Parameter to ADO Function Gives Error =

Article ID: 295692

Article Last Modified on 8/23/2001

-

APPLIES TO


 * Microsoft ActiveX Data Objects 2.0
 * Microsoft ActiveX Data Objects 2.1
 * Microsoft ActiveX Data Objects 2.5
 * Microsoft ActiveX Data Objects 2.6
 * Microsoft Visual C++ 6.0 Service Pack 5
 * Microsoft Visual J++ 6.0 Standard Edition

-



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( &quot;Some SQL Statement&quot;, &vtMissing, adCmdText ); you can change it to the following: conn->Execute( &quot;Some SQL Statement&quot;, NULL, adCmdText );



STATUS
This behavior is by design.



Steps to Reproduce Behavior
 Use the Visual C++ App Wizard to generate a Win32 Console application.  Paste the following code in a .cpp file of the application:
 * 1) undef EOF
 * 2) import &quot;c:\program files\common files\system\ado\msado15.dll&quot; no_namespace
 * 3) include 
 * 4) include 

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( &quot;Provider=SQLOLEDB;Server=Myserver;Database=Pubs;UID=sa;PWD=;&quot;, &quot;&quot;, &quot;&quot;, -1 );

// First open works fine. rs->PutRefActiveConnection( conn ); rs->Open( &quot;select * from authors&quot;, vtMissing, adOpenKeyset, adLockOptimistic, adCmdText ); rs->Close; rs->PutRefActiveConnection( NULL );

// Pass vtMissing as an output parameter. conn->Execute( &quot;update authors set au_id=au_id where 1=0&quot;, &vtMissing, adCmdText ); // To remove the problem, comment the previous line and uncomment the following line. //conn->Execute( &quot;update authors set au_id=au_id where 1=0&quot;, NULL, adCmdText );

// When you open the same recordset again, it fails because ADO has modified vtMissing. rs->PutRefActiveConnection( conn ); rs->Open( &quot;select * from authors&quot;, vtMissing, adOpenKeyset, adLockOptimistic, adCmdText ); rs->Close; rs->PutRefActiveConnection( NULL );

}   catch ( _com_error ex ) {

printf( &quot;Com error %s (hr=0x%08x) thrown.\n&quot;, (char*) ex.Description, ex.Error );

for ( long i=0; iErrors->Count; i++ ) {           printf( &quot;Error[%lu] %s.\n&quot;, i, (char*) conn->Errors->Item[i]->Description ); }   }

printf( &quot;Test complete. Press any key to exit.\n&quot; ); _getch;

}                    Modify the connection string to your own. Compile and then run the application. Note that the second Open call fails with the error message shown in the &quot;Symptoms&quot; section because vtMissing has been changed by ADO.</li></ol>

<div class="references_section">