Skip to main content
gamedev.net
🔒 Locked

COM Error : Type mismatch

Started by graveyard filla 2 replies 1k views
Original Post
graveyard filla
graveyard filla
Hi, I'm working on an application which uses ADO and C++ to communicated with an MSSQL database. I wrote a little wrapper over ADO to make things simpler. Anyway, for some reason, I am getting a _com_error exception thrown when running certain queries on certain tables. For example, I can run an insert statement on a table but not a select statement, but running select statements on a different table works fine. Anyway, here's the function I wrote which should allow me to run a query and have the result returned as a std::map<std::string,std::string>, where 'first' is the name of the field and 'second' is the value. This let's me do something like player.name = result.Get_By_Name("Name").

bool Database::Run_Query(const std::string &query, Result &result) 
{
	 _RecordsetPtr  recordset;

     HRESULT hr = recordset.CreateInstance(__uuidof(Recordset));

	 if(FAILED(hr))
     {
		return false;
     }

    _variant_t index;
    index.vt = VT_I2;

    try
    {
        recordset->Open(query.c_str(), conn.GetInterfacePtr(), adOpenForwardOnly,adLockReadOnly, adCmdText);

		int count = 1;
   
		while(recordset)
        {
            while(!recordset->EndOfFile)
            {
				//create a row that we will add to the result
				std::map<std::string,std::string> row;

				//fill the row with the data
				for(int i = 0; i < recordset->Fields->Count; ++i)
				{
					index.iVal = i;

					std::string name = recordset->GetFields()->GetItem(&index)->Name;
					std::string val  = (_bstr_t)recordset->GetFields()->GetItem(&index)->Value; // <-- this ones throwing exception
							
					//I tried this as well, but it doesn't work either
					//_variant_t var1;
					//var1 = recordset->Fields->GetItem(&index)->GetName();

					//_variant_t var2;
					//var2 = recordset->Fields->GetItem(&index)->GetValue();
					//
					//std::string name = (_bstr_t)var1;
					//std::string val = (_bstr_t)var2;

					row.insert(std::make_pair(name,val));
				}

				//now add this row to the result
				result.Add_Row(row);

                recordset->MoveNext();
            }
            
			long lngRec = 0;
         
			recordset = recordset->NextRecordset((VARIANT *)lngRec);
           
			count++;
        }
    }
    catch(_com_error &e)
    {
		cout << "COM Error inside Database::Run_Query() :"<< e.ErrorMessage() << endl;
		return false;
    }

    // Clean up objects before exit.
    if (recordset)
        if (recordset->State == adStateOpen)
            recordset->Close();

	return true;
}



Notice inside the for(int i = 0; i < recordset->Fields->Count; ++i) loop I have commented out code.. this was a nother way I tried to get the data but that gave the same problem. I've been searching through tutorials and MSDN but can't find any help for this problem. Thanks for any help.
FTA, my 2D futuristic action MMORPG
graveyard filla
graveyard filla
AP,

Thanks for the reply, but.. I'm a little confused.. if Count was 0, then won't that for loop never get executed?

Also, I don't think this is the problem... im running the exact same query cut and pasted from Query Analyzer and it works fine (the query definetly has > 0 records)...

Thanks for any more help.
FTA, my 2D futuristic action MMORPG
mfawcett
mfawcett
The AP was obviously wrong about the for loop. As for the code, I think your commented out code is closer to being correct. You should catch the return in a variant. Then examine what type the variant is holding, and act accordingly.
--Michael Fawcett

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.