Library tutorials & articles
Using ADO in C++
Introduction
I'm often asked for a HowTo tutorial on using ADO with C++. It is highly likely that I've written more ADO with C++ than anybody on the planet. I often talk about how nice it is to do database programming with ADO and C++. But this combination never made the mainstream of programming.
Programming with ADO in C++ is just as easy as with Visual Basic, you just have to explicitly release COM objects, handle exceptions and work with those nasty C++ pointers. But all in all, if you can handle the added complexity of C++, then you should be able to create much more robust applications then with junior languages like Visual Basic. The best way to use ADO in C++ is to use the smart pointers created with the #import directive in Visual C++.
#import "C:\Program files\Common Files\System\Ado\msado15.dll"
rename("EOF", "ADOEOF")
This eliminates the one of our concerns about C++, that is, explicitly releasing COM objects. The smart pointers, if used correctly, should release the objects appropriately.
Related articles
Related discussion
-
WinGDB - Linux debugging under Visual Studio
by WinGDB (0 replies)
-
Programmers in Trinidad and Tobago
by alacom (1 replies)
-
Can somebody help: CAsyncSOcket class (Client-server networking)
by chong (7 replies)
-
Weird problem for devenv command build failed.
by anson78 (0 replies)
-
Binary Studio | software development outsourcing Ukraine
by Hexfinity (2 replies)
yes , it can be used, but in this case , compiler will treat it as auto variable. Compiler will only generate warning.
can we use register variable for storing address
Hi,
Does anyone know how to use C language (not C++) with ADO and/or ODBC againt SQL Server. Any sample or a link to a sample is very much appreciated. Thanks in advance.
Rass
Now show me how to add a new record to the database. After many hours of working on this, I finally got the program to retrieve the records from the Access database, but I have no idea how to add a new record to the database using ADO. It just ignores me.
Hi,
The #import directive is used to incorporate information from a type library. The content of the type library is converted into C++ classes, mostly describing the COM interfaces.
The backslash ('\') symbol is used to include additional lines in a single #import statement. Basically its a line continuation symbol whenever the single statement breaks in multiple line.
import "C:\Program files\Common Files\System\Ado\msado15.dll" rename("EOF", "ADOEOF")
The above line is a single statement having some attributes for the import directives. The rename is one of the attribute for the import directive. Some of the attributes are given below
exclude implementationonly
include(…) namedguids noautoexclude
noimplementation nonamespace
rawpropertyprefixes rename
rename_namespace
Can anyone help me figure out how to bind the ADO Recordset to a DataGrid control?
I'm having problems with any table over two columns. Any help would be greatly appreciated. Thanks
Anyone have any problems with this and winsock?
It would be really awesome to use this but I am getting some of the following and lots more.
IncludePath\WinSock2.h(109) : error C2011: 'fdset' : 'struct' type redefinition
IncludePath\WinSock.h(54) : see declaration of 'fdset'
IncludePath\WinSock2.h(144) : warning C4005: 'FDSET' : macro redefinition
IncludePath\WinSock.h(88) : see previous definition of 'FDSET'
IncludePath\WinSock2.h(153) : error C2011: 'timeval' : 'struct' type redefinition
IncludePath\WinSock.h(97) : see declaration of 'timeval'
IncludePath\WinSock2.h(209) : error C2011: 'hostent' : 'struct' type redefinition
IncludePath\WinSock.h(153) : see declaration of 'hostent'
IncludePath\WinSock2.h(222) : error C2011: 'netent' : 'struct' type redefinition
IncludePath\WinSock.h(166) : see declaration of 'netent'
IncludePath\WinSock2.h(229) : error C2011: 'servent' : 'struct' type redefinition
IncludePath\WinSock.h(173) : see declaration of 'servent'
IncludePath\WinSock2.h(241) : error C2011: 'protoent' : 'struct' type redefinition
IncludePath\WinSock.h(185) : see declaration of 'protoent'
IncludePath\WinSock2.h(397) : error C2011: 'sockaddr_in' : 'struct' type
I shortened the include path from c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include to IncludePath to make it more readable.
I originally had the same problem as the others with VS .NET 2003 without the \ at the end of the #import, now I am getting this.
If I instead do the #import after the thing I have that includes winsock I get
ProjectPath\msado15.tlh(893) : error C2146: syntax error : missing ';' before identifier 'NewEnum'
ProjectPath\msado15.tlh(893) : error C2501: 'ADODB::Collection::IUnknownPtr' : missing storage-class or type specifiers
ProjectPath\msado15.tlh(893) : warning C4183: '_NewEnum': missing return type; assumed to be a member function returning 'int'
ProjectPath\msado15.tlh(1136) : error C2146: syntax error : missing ';' before identifier 'DataFormat'
ProjectPath\msado15.tlh(1136) : error C2501: 'ADODB::Field20::IUnknownPtr' : missing storage-class or type specifiers
ProjectPath\msado15.tlh(1136) : error C2501: 'ADODB::Field20:
ProjectPath\msado15.tlh(1158) : error C2146: syntax error : missing ';' before identifier 'GetDataFormat'
...basically it has no idea what a IUnkownPtr is and im not sure why.
As a side note, the article is very cool and looks to be very promising, much easier/flexible than what I was using.
JP.
I made some changes... maybe now it works in Dev CPP
include <iostream.h>
import "C:\Program files\Common Files\System\Ado\msado15.dll" rename("EOF", "ADOEOF")
void main()
{
HRESULT hr;
CoInitialize(NULL);
try
{
ADODB::ConnectionPtr conn;
hr = conn.CreateInstance(uuidof(ADODB::Connection));
if (FAILED(hr))
{
throw _comerror(hr);
}
ADODB::RecordsetPtr rs;
hr = rs.CreateInstance(uuidof(ADODB::Recordset));
if (FAILED(hr))
{
throw _comerror(hr);
}
conn->Open(L"Data Source=Databasename;User Id=username;Password=password;", L"",
L"",-1);
rs->Open("select * from table",
conn.GetInterfacePtr(),
ADODB::adOpenForwardOnly,
ADODB::adLockReadOnly,
ADODB::adCmdText);
while(!rs->ADOEOF)
{
variantt var;
var = rs->Fields->GetItem(L"columname")->GetValue();
cout << _bstrt(var.bstrVal) << endl;
rs->MoveNext();
};
rs->Close();
}
catch(comerror &e)
{
cout << e.Description();
}
catch(...)
{
cout << "Unhandled Exception";
};
CoUninitialize();
}
I am using Dev Cpp (from www.bloodshed.net) and it does not seem to support this way.
Any ideas & suggestions are welcome. Thanx Leos
By the way, if working with OleDb types in MS ADO / MFC C++,
this little snippet may be of use to you (tested on XP and Win2000)
// Connection ...
// variables here are mvwin32SQLsrvName_1, and mvwin32SQLsrvDB_1
// 1433 is default port
CString connectionString = "Provider=SQLOLEDB;Data Source=" + mvwin32SQLsrvName_1 + ",1433;Network Library=DBMSSOCN;Initial Catalog=" + mvwin32SQLsrvDB_1 + ";" + "Trusted_Connection=Yes;";
_ConnectionPtr m_pConn;
m_pConn.CreateInstance (__uuidof(Connection));
m_pConn->Open( _bstr_t( connectionString ), _bstr_t( "" ), _bstr_t( "" ), adModeUnknown );//
// Command ...
_CommandPtr pCommand;
pCommand.CreateInstance (__uuidof (Command));
pCommand->ActiveConnection = m_pConn; // Formerly opened connection
pCommand->CommandText = (_bstr_t) chosenQuery;
// Recordset ...
_RecordsetPtr pRecordset;
pRecordset.CreateInstance (__uuidof (Recordset));
pRecordset->CursorLocation = adUseClient;
pRecordset->Open ( (IDispatch *) pCommand, vtMissing, adOpenStatic, adLockBatchOptimistic, adCmdUnknown);
while (!pRecordset->GetadoEOF())
{
variant_t vtFieldValue;
vtFieldValue = pRecordset->Fields->GetItem((_bstr_t) column)->Value;
// all numeric types verified by Microsoft's OLE DB Programmer's Reference
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/oledb/htm/olprappendixa_1.asp
// types of VARENUM, show by typing "VARENUM::" in .NET 2003
if ((vtFieldValue.vt == VT_CY) || (vtFieldValue.vt == VT_DECIMAL) || (vtFieldValue.vt == VT_I1) || (vtFieldValue.vt == VT_I2) || (vtFieldValue.vt == VT_I4) || (vtFieldValue.vt == VT_I8) || (vtFieldValue.vt == VT_INT) || (vtFieldValue.vt == VT_R4) || (vtFieldValue.vt == VT_R8) || (vtFieldValue.vt == VT_UI1) || (vtFieldValue.vt == VT_UI2) || (vtFieldValue.vt == VT_UI4) || (vtFieldValue.vt == VT_UI8) || (vtFieldValue.vt == VT_UINT))
{
double num = (double) vtFieldValue;
}
else
{
CString str = (CString) vtFieldValue;
}
} // end while
I've just had the same problem, I solved it with these steps:
1) move
#import "C:\Program files\Common Files\System\Ado\msado15.dll" \
rename("EOF", "ADOEOF")
to the stdafx.h file (note that I've added a '\' at the end of the first line.
2) make sure #include "stdafx.h" appears before any #includes in your main file.
hopefully that will then compile.
Andy,
I'm using Visual Studio .NET 2003, and when I place the statements
import "C:\Program files\Common Files\System\Ado\msado15.dll"
rename("EOF", "ADOEOF")
into a header file, and include the header in a sample project with no compilation or linkage errors,
I get the following errors:
Notice the rename errors, I thought that was ok?
c:\Documents and Settings\Dan\My Documents\Visual Studio Projects\ADOEx\Debug\msado15.tlh(2375): error C2059: syntax error : '-'
c:\Documents and Settings\Dan\My Documents\Visual Studio Projects\ADOEx\dataDlg.h(5): error C2078: too many initializers
c:\Documents and Settings\Dan\My Documents\Visual Studio Projects\ADOEx\dataDlg.h(5): error C2143: syntax error : missing ';' before '<class-head>'
c:\Documents and Settings\Dan\My Documents\Visual Studio Projects\ADOEx\Debug\msado15.tlh(2375): error C2238: unexpected token(s) preceding ';'
c:\Documents and Settings\Dan\My Documents\Visual Studio Projects\ADOEx\dataDlg.h(5): error C2365: 'rename' : redefinition; previous definition was a 'function'
c:\Documents and Settings\Dan\My Documents\Visual Studio Projects\ADOEx\dataDlg.h(5): error C2440: 'initializing' : cannot convert from 'const char [7]' to 'int'
c:\Documents and Settings\Dan\My Documents\Visual Studio Projects\ADOEx\dataDlg.h(5): error C2501: 'rename' : missing storage-class or type specifiers
This thread is for discussions of Using ADO in C++.