Take over a project, you need to access the existing Paradox database with VC. Before the project, there is less understanding of Paradox, only to know such a database, do not understand what it is. When you actually operate it, it's hard to find it. There are almost gave up, but the last bite, I finally insisted. During this time, I walked a lot of detours, and I also have some experience. Let's write down, as a summary, and take a little prompt for other equivalents. 1. Paradox Database Structure Paradox Database is Boland's desktop database that uses BDE before Delphi. It is currently rarely used, so that ADO does not provide its engine (it also harms me a lot of suffering). The ParaDox database itself exists with a separate table, a table can be seen as a library, or it can be said to be a folder is a library, the Paradox data table in the folder is the table of the library. The extension of the ParaDox data sheet is DB, and there are some other file types, as the auxiliary of the data table, but when processed with ADO, the file with * .db is sufficient. 2, before connecting to the Paradox database, Ado does not have a PARADOX database engine, and I have to use ADO to access the Paradox database, I have tried three ways: use microsoft.jet.OleDb.4.0 to replace the Paradox database engine; Use an imitation ODBC's connection statement operation; establish an ODBC data source, then use ADO to access ODBC. Another is to encapsulate the BDE API with VC, which can be found on ww.codeproject.com. For the last method, use his example, but it is very effective, but it is very powerful when it is truly moving to my program, and the effect is not good. It is mainly what I don't understand the BDE operation. For a lot of time, I finally waive the end. Below I will explain the operation of connecting to the database with the first three ways. In fact, these three ways are not too big, but the connection statements are different. (1) Use the Microsoft.jet.OleDb.4.0 engine.
This way is access to other databases when accessing to other databases: _ConnectionPtr M_PDB; CString ConnectSource; ConnectSource.Format (L "provider = microsoft.jet.Oledb.4.0; data source =% s // shared; extended Properties = Paradox 5. x; persist security info = false ", struntrsroute); try // check if the database connection is normal {m_pdb.createInstance (__ uuidof (connection)); m_pdb-> connectionTIMEOUT = 10; m_pdb-> commandtimeout = 20; if (m_pdb-> State! = AdStateclosed) {m_pdb-> close (); m_pdb-> open ((_ bstr_t) connectsource, ",", ", admodeunknown);} else {hr = m_pdb-> open ((_ bstr_t) connectsource," ", "", admodeunknown;}} catch (_COM_ERROR E) // capture exception {logadoErrorImport (m_pdb);} Description: The connection information saves the connection information, where we can see that the so-called database data source, only means connection To the location of the Paradox data, Data Source =% s // shared, "Shared" is a folder name, and there is a paradox data table below this folder, not which data table is pointed out. Similarly, in two ways, the data source also points only to a folder containing the Paradox data sheet. In addition to the abnormal processing, other operations are not different from other ADO operations, which is no longer redundant. (2) Use imitation ODBC connection operation. ODBC also provides a ParaDox data engine, so we can access the Paradox data table via ODBC. This method is to write the connection information of the establishment of DSN in ADO's connection statement. ConnectSource.Format (L "collatingsequence = ASCII; DBQ =% s // shared;" / L "defaultdir =% s // shared; driver = {microsoft paradox driver (* .db)};" / l "driverid = 538 Fil = paradox 5.x; "/ L" Maxbuffersize = 2048; MaxScanRows = 8; PageTimeout = 600; "/ L" paradoxnetpath =% s // shared; paradoxnetStyle = 4.x; paradoxusername = admin; "/ L" Safetransactions = 0; threads = 3; UID = 3; usercommitysync = yes; "Strctorroute, strCTRSROUTE, STRCTRSROUTE, STRCTRSROUTE); Description: The above can be found directly below the ODBC in the registry or all file DSN. We now operate the Paradox data sheet, usually Paradox 4.x or Paradox 5.x.
There is no power for Paradox 7.x. Fortunately, the version of the database I use is not so high, huh, huh. Other operations are the same. (3) Establish an ODBC data source to access the ODBC data source with ADO. This method is the second release, but it needs to be dynamically or manually add ODBC data sources. CString ConnectSource = "provider = msdasql.1; Persist security info = false; data source = projdir"; where Data Source = Projdir, the data source is a DSN for an ODBC.
To achieve dynamically added data sources, a function adding a Paradox system DSN: BOOL loadDBSource (CString strsourceName, cstring strsourcedb, cstring strscription) {// store open registry keys HKEY HKEY; DWORD DW; // Store Registry The return value of the API function executes long Lreturn; // stores the subkey cstring strsubkey to open; // detects whether the MS Access ODBC DRIVER: ODBCJT32.DLL // Get the Windows System Directory Wchar Sysdir [MAX_PATH]; Wchar Drvname [] = L "// odbcjt32.dll"; :: getSystemDirectory; wcscat (sysdir, drvname); cfilefind findfile; if (! Findfile.findfile (sysdir)) {AFXMESSAGEBOX (L "No installation Paradox 5.x ODBC driver odbcjt32.dll, / N unable to load this class data source! ", MB_OK | MB_ICONSTOP); return false;} strsubkey = L" Software // odbc // odbc.ini // " strsourceEName; // creation ODBC data source in the registry subkeys lReturn = :: RegCreateKeyEx (HKEY_LOCAL_MACHINE, (LPCTSTR) strSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, & hKey, & dw); if (! lReturn = ERROR_SUCCESS) return FALSE; // Set the parameters of the data source cstring strdbq = strsourcedb; cstract dwdriver = sysdir; dword dwdriverid = 538; cstract dwdriverid = 538; cstring strfil = "paradox 5.x;"; // cstring strpwd = strsourceEName; DWORD DWSAFETRANSACTI Ons = 0; cstring struid = l "admin"; :: RegSetValueex (HKEY, L "defaultdir", 0L, reg_sz, (const Byte *) ((lpcwstr) strdbq), 2 * strdbq.getlength ()); :: RegSetValueex (HKEY, L "Description", 0L, REG_SZ, (Const Byte *) ((lpcwstr) strdescription, 2 * strDescription.getLength ()); :: RegSetValueex (HKEY, L "driver", 0L, REG_SZ, Const Byte *) ((lpcwstr) striver, 2 * strdriver.getlength ()); :: RegSetValueEx (HKEY, L "driverid", 0L, reg_dword, (const Byte *) (& DWDRIVERID), SIZEOF (DW)); :: RegSetValueex (HKEY, L "FIL", 0L, REG_SZ, (Const Byte *) ((lpcwstr) Strfil, 2 * Strfil.getLength ()); :: RegSetValueex (HKEY, L "UID"
, 0L, REG_SZ, (LPCTSTE *), 2 * STRUID.GETLENGTH ()); :: RegSetValueex (HKEY, L "SafeTransactions", 0L, Reg_dword, (Const Byte *) (& DWSAFETRANSACTION), SizeOf (dw)); :: regclosekey (HKEY); // Create an ODBC data source JET sub-key strsubkey = "// Engines // paradox"; lreturn = :: regreateKeyex (HKEY_LOCAL_MACHINE, (LPCWSTR) strsubkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, & hKey, & dw); if (lReturn = ERROR_SUCCESS) return FALSE;! // set the parameters CString strImplict = "in the sub-key"; CString strUserCommit = "Yes"; DWORD dwPageTimeout = 5; DWORD dwThreads = 3; DWORD dwMaxBufferSize = 2048; CString strCollSeq = L "ASCII"; CString strParadoxNetStyle = L "4.x"; :: RegSetValueEx (hKey, L "ImplicitCommitSync", 0L, REG_SZ, (CONST BYTE *) ((Lpcwstr) StrimPLICT, 2 * Strimplict.getLength () 1); // :: RegSetValueex (HKEY, L "maxbuffersize", 0L, reg_dword, (const Byte *) (& DWMAXBUFFERSIZE), SIZEOF (DW)); :: RegSetValueex (HKEY, L "Pagetimeout", 0L, Reg_dword, (Const Byte *) (& DWPAGETIMEOUT), SIZEOF (DW)); :: RegSetValueex (HKEY, L "threads", 0L, REG_DWORD, (CO NST Byte *), Sizeof (DW)); :: RegSetValueex (HKEY, L "UserCommitsync", 0L, Reg_SZ, (Const Byte *) ((LPCWSTR) StruserCommit, 2 * StruserCommit.getLength ()); :: RegSetValueex (HKEY, L "Collatingsequence", 0L, REG_SZ, (Const Byte *) ((LPCWSTR) Strcollseq), 2 * Strcollseq.getlength ()); :: RegSetValueex (HKEY, L "ParadoxNetPath", 0L, REG_SZ (Const Byte *) (LPCWSTR) STRDBQ, 2 * Strdbq.getLength ()); :: RegSetValueex (HKEY, L "ParadoxnetStyle", 0L, Reg_SZ, (Const Byte *) ((LPCWSTR) STRPARADOXNETSTYLE, 2 * strparadoxnetStyle.getLength ()); :: RegSetValueex (HKEY, L "Paradoxusername"
, 0L, Reg_SZ, (LPCWSTR) STRUID, 2 * STRUID.GETLENGTH ()) ;: regcloseKey (HKEY); // Set ODBC Database Engine Name Lreturn = :: RegOpenKeyex (HKEY_LOCAL_MACHINE, L " Software // ODBC // Odbc.ini // ODBC Data Source ", 0L, Key_Write, & HKey); if (Lreturn! = Error_Success) Return False; cstring strident = L" Microsoft Paradox Driver (* .db) "; ::: RegSetValueex (HKEY, STRSOURENAME, 0L, REG_SZ, (Const Byte *) ((lpctstr) strdbtype), 2 * strdbtype.getLength ()); return true;} Description: This function is an example of writing an ODBC registry online The processing is made, thank you here! When establishing a system DSN, an item is ParadoxUserName. When you use the ODBC manager to add a data source, you will default to the login name of the current user. And this is a must. In order to reduce the trouble of obtaining the current system user, it assigns its value to: "amdin", and no negative impact is generated during the actual operation. The above is actions connected to the database. All of the above operations don't have much difference. 3. Operation of the data sheet, after connecting to the database, the operation of the data table is very easy. But I spent a lot of time and effort on this link, so that the development time is added again. I don't want to say too much for the operation of the table, but there is a problem in this. I didn't really study what the PARADOX underlying principle is, but when actual operation, it finds that it has strong dependence on BDE. Due to the database products developed with BDE on my computer, all operations are all normal. But when the system gets a lot of problems on other computers, the most important one is an error that appears "[odbc paradox] external data sheet is not expected". Later, after a number of computers, it may be caused by BDE. Later, after installing BDE on a problem, everything is gone. 4. Error handling Originally, when operating the ADO, the error handling is the necessary steps, but how to perform erroneous processing can also affect the robust and stability of the program. Under normal circumstances, we all use the _COM_ERROR object to provide error message, during this process, I don't know the true information of the wrong, but some ambiguous information such as: 3092, Dispatch error, etc., for us to solve the problem How much effect. The wrong information is the best way to use the ERROR object of the ADO itself. It can capture all the information of all connection, command, and recodset, which is obtained from www.codeproject.com.
Thanks for the author of the function! HRESULT LogAdoErrorImport (_ConnectionPtr pConn) {ErrorsPtr pErrors; ErrorPtr pError; CString strTmp; HRESULT hr = (HRESULT) 0L; long nCount; // Do not have an un-handled exception in the handler that // handles exceptions try {pErrors! = PCONN-> getErrors (); ncount = perrors-> getCount (); for (long i = 0; (! failed (hr)) && (i