Method for dynamic loading ODBC in VC

xiaoxiao2021-03-06  15

When writing database applications using high-level languages ​​such as VC, VB, Delphi, users often need to configure ODBC data sources in the control panel. For general users, configuring ODBC data sources may be a relatively difficult job. Moreover, in practical applications, users tend to access different data sources in the same application, so the general loading method has a defect that cannot be overcome. In order to complete this work in the program, it is convenient for the application of the application. This article describes two ways to dynamically load an ODBC system data source in the application in VC.

Method 1: Modify the registry

Design ideas

In general, when the user is configured in the control panel, the Windows system adds some sub-keys to the registry to store the user's configuration. When the application needs to use the data source, Windows will notify the underlying interface to see the configuration of the data source in the registry. If the user deletes an ODBC data source, it will also react in the registry. If the configured data source is a user data source, the Windows system will modify the hkey_current_user / software / uf键 / ODBC.ini subkey of the registry; if the configuration of the data source is a system data source, the Windows system will modify the hkey_local_machine / Software / ODBC / ODBC.INI master key. Therefore, we can use the registry editing function in the Windows API to complete the work made by the registry in the application, which can achieve the purpose of dynamically loaded data sources.

Implementation

For different types of data sources, the modification of the registry is also different, but it is basically modified two places. One is a sub-key that is the same name with the data source description name under the ODBC.ini sub-key and establishes the item related to the data source configuration under the subkey; the other is under the odbc.ini / odbc data sources subkey Establish a new item to tell the driver manager ODBC data source. The following is to configure a Microsoft Access data source to give a code that implements this function.

/ * STRSourceName is the data source to create, and strsourceDB is a data stock path, and StRDESCRIption is a description string of the data source. * /

Bool Cloadodbcdlg :: loaddbsource (CString strsourcename, cstring strsourcedb, cstring strdescription)

{

/ / Store opened registry keys

HKEY HKEY;

DWORD DW;

/ / Store the return value of the registry API function

Long Lreturn;

/ / Store the subkey to be opened

Cstring strsubkey;

// Test if MS Access ODBC Driver: ODBCJT32.DLL is installed

// Get a Windows System Directory

CHAR SYSDIR [MAX_PATH];

Char drvname [] = "// odbcjt32.dll";

:: GetSystemDirectory (sysdir, max_path);

STRCAT (SYSDIR, DRVNAME);

CfileFind Findfile;

IF (! findfile.findfile (sysdir))

{

AFXMessageBox ("Your computer system does not have MS Access ODBC driver odbcjt32.dll, you will not be able to load this class data source.", MB_OK | MB_ICONSTOP);

Return False;

}

strsubkey = "Software // ODBC // ODBC.INI //" STRSOURCENAME;

// Create a child key in the registry in the registry

Lreturn = :: regREATEKEYEX (HKEY_LOCAL_MACHINE, (LPCTSTSTSTR) 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;

CString strodr = sysdir;

DWORD DWDRIVERID = 25;

Cstring strfil = "ms access;";

CString strpwd = strsourceEName;

DWORD DWSAFETRANSACTIONS = 0;

CString struid = strsourceEName;

:: RegSetValueex (HKEY, "DBQ", 0L, REG_SZ, (Const Byte *) ((lpctstr) strDbq, strdbq.getlength ());

:: RegSetValueex (HKEY, "Description", 0L, REG_SZ, (Const Byte *) ((lpctstr) strdescription, strdescription.getLength ());

:: RegSetValueex (HKEY, "Driver", 0L, REG_SZ, (Const Byte *) ((lpctstr) strdriver, strDriver.getlength ());

:: RegSetValueex (HKEY, DRIVERID ", 0L, Reg_dword, (Const Byte *), SIZEOF (DW));

:: RegSetValueex (HKEY, "FIL", 0L, REG_SZ, (Const Byte *) ((lpctstr) Strfil, Strfil .getLength ());

:: RegSetValueex (HKEY, "PWD", 0L, REG_SZ, (Const Byte *) ((LPCTSTE *) () StrPwd.getLength ());

:: RegSetValueex (HKEY, "Safetransactions", 0L, REG_DWORD, (Const Byte *), SizeOf (DW));

:: RegSetValueex (HKEY, "UID", 0L, REG_SZ, (Const Byte *) ((LPCTSTE *), STRUID.GETLENGTH ());

:: regcloseKey (HKEY);

// Create the JET subkey for the ODBC data source

STRSUBKEY = "// Engines // jet";

Lreturn = :: regReateKeyex (HKEY_LOCAL_MACHINE, (LPCTSTSTSTSTSTSTSTSTSTSTSTSTSTSUBKEY, 0, NULL, REG_OPTION_NON_VOLATILE, Key_Write, Null, & HKEY, & DW)

IF (Lreturn! = Error_Success)

Return False;

/ / Set the parameters under the subkey

CString strimplict = "";

CString struserCommit = "yes";

DWORD dwpagetimeout = 5;

DWORD DWTHREADS = 3;

DWORD dwmaxbuffersize = 2048; :: RegSetValueex (HKEY, ImplicitCommitsync ", 0L, Reg_SZ, (Const Byte *) ((LPCTSTSTR) Strimplict, StrimPlict.getLength () 1);

:: RegSetValueex (HKEY, "MaxBuffersize", 0L, REG_DWORD, & DWMAXBUFFERSIZE, SIZEOF (DW));

:: RegSetValueex (HKEY, "Pagetimeout", 0L, REG_DWORD, (CONST BYTE *), SIZEOF (DW));

:: RegSetValueex (HKEY, "Threads", 0L, REG_DWORD, (Const Byte *), SizeOf (DW));

:: RegSetValueex (HKEY, "UserCommitsync", 0L, REG_SZ, (Const Byte *) ((lpctstr) StruserCommit, StruserCommit.getlength ());

:: regcloseKey (HKEY);

/ / Set the name of the ODBC database engine

Lreturn = :: regopenkeyex (HKEY_LOCAL_MACHINE, "Software // ODBC // Odbc.ini // ODBC Data Sources", 0L, Key_Write, & HKey

IF (Lreturn! = Error_Success)

Return False;

CString strdbtype = "Microsoft Access Driver (* .mdb)";

:: RegSetValueex (HKEY, STRSOURENAME, 0L, REG_SZ, (Const Byte *) ((LPCTSTE *) () StrDbType.getLength ());

Return True;

}

Since the database file, data source description, and data source description are generally changed in dynamic loading, the above functions can implement most of the requirements in the application. If more changes are required in the application, you can also be implemented by changing the function parameters. For conditions that need to be dynamically loaded multiple types of data sources, you can use the overload function with different parameters.

Method 2: Using DLL

Design ideas

Dynamic Link Library ODBCINST.DLL in the Windows system subdirectory provides a function of functionality () that can be dynamically increased, modified, and delete data sources. The prototype of this function is as follows:

Bool SqlconfigDataSource (HWND HWndParent, Word Frequest, LPCSTR LPSZDRIVER, LPCSTR LPSZATTRIBUTES);

The hwndparent parameter is a parent window handle. If this value is NULL, the dialog related to the parent window will not appear.

The FREQUEST parameter can be set to one of the values ​​below:

ODBC_ADD_DSN: Add a new user data source;

ODBC_Config_DSN: Modify (Configure) an existing user data source;

ODBC_Remove_DSN: Delete an existing user data source;

ODBC_ADD_SYS_DSN: Add a new system data source;

ODBC_CONFIG_SYS_DSN: Modify (Configure) an existing system data source;

ODBC_Remove_sys_dsn: Delete an existing system data source. The LPSZDRIVER parameter is used to transfer the name of the database engine, equivalent to the strDbType variable in the method.

The lpszattirbutes parameter is the value of the keyword, that is, a series of "keyname = value" string, with "/" all over two strings, such as DSN = Personnel Data / 0uid = Smith / 0DATABASE = Personnel. See the help documentation of the SQLConfigDataSource () function in the MSDN and a variety of ODBC driver documents for the detailed settings for this parameter.

Implementation

Since the VC's default library file does not include a SQLConfigDataSource () function, you need to include the ODBCINST.H file in the project's header file before you use the function, editing the Object / Library Modules for the SETTINGS Properties dialog box LINK Properties page. In the box, ODBCCP32.LIB is added, while ensuring that there is file odbcp32.dll under System Directory System32.

Taking Microsoft Access as an example, set the data source name to DEMO, the data source is described as "sample data source", then add the following code to where you need to dynamically load the data source:

:: SQLConfigDataSource (NULL, ODBC_ADD_SYS_DSN, "Microsoft Access Driver (* .mdb)", "DSN = DEMO / 0DESCRIPTION = Sample Database");

summary

Both of the above methods can realize dynamically load various types of ODBC data sources, and are debugged in the Windows 95/98 / NT / 2000 environment. Methods A more code is required when implementing, the code is minus code, but requires additional file support, and with the increase in the flexibility of the data source configuration, in order to form the LPSZATTRIBUTES string, the length of the code will also correspond increase. Since the data source is configured from the control panel allows the programmer to get more intuitive understanding, the programmer can also pass the programming in addition to the documentation of the relevant driver in the registry and the corresponding item name. The control panel configures the ODBC data source and then programs according to the contents of the corresponding part in the registry.

Netizen: HYSC (Hysc@163.com) Published in: 2004-10-15 12:21:17 Program has an error // Set the ODBC database engine name Lreturn = :: regopenkeyex (HKEY_LOCAL_MACHINE, "Software // ODBC // ODBC. Ini // ODBC Data Sources ", 0L, Key_WRITE, & HKEY); if (Lreturn! = Error_Success) Return False If ODBC has not been built, the" Software / ODBC / ODBC.INI / ODBC DATA SOURCES "should be built first! ^ _ ^

转载请注明原文地址:https://www.9cbs.com/read-49842.html

New Post(0)