¿Por qué es necesario configurar una fuente de datos para la programación de bases de datos?
Al escribir aplicaciones de bases de datos utilizando lenguajes de alto nivel como VC, VB y Delphi, los usuarios a menudo necesitan configurar la fuente de datos ODBC en el panel de control. Para el usuario medio, configurar una fuente de datos ODBC puede ser una tarea desalentadora. Además, en aplicaciones prácticas, los usuarios a menudo necesitan acceder a diferentes fuentes de datos en la misma aplicación, por lo que el método de carga general tiene fallas insuperables. Para completar este trabajo en el programa y facilitar el uso de la aplicación, este artículo presenta dos métodos para cargar dinámicamente fuentes de datos del sistema ODBC en la aplicación utilizando VC como entorno de desarrollo.
Método 1: Modificar el registro.
Concepto de diseño
En términos generales, cuando un usuario configura una fuente de datos ODBC en el panel de control, el sistema Windows agregará algunas subclaves al registro para almacenar los resultados de la configuración del usuario. Cuando una aplicación requiere una fuente de datos, Windows notifica a la interfaz subyacente para consultar la configuración de la fuente de datos en el registro. Si un usuario elimina una fuente de datos ODBC, también se reflejará en el registro. Si la fuente de datos configurada es una fuente de datos de usuario, Windows modificará la subclave HKEY_current_user\software\odbc\odbc.ini del registro. Si la fuente de datos configurada es una fuente de datos del sistema, el sistema Windows modificará la clave principal HKEY_Local_Machine\Software\odbc\odbc.ini del registro. Por lo tanto, podemos utilizar la función de edición del registro en la API de Windows en la aplicación para completar el trabajo realizado por Windows, logrando así el propósito de cargar dinámicamente fuentes de datos.
Implementación específica
Para diferentes tipos de fuentes de datos, las modificaciones del registro también son diferentes, pero hay básicamente dos lugares donde se pueden modificar. Una es crear una subclave con el mismo nombre que el nombre de descripción de la fuente de datos bajo la subclave ODBC. INI y cree el elemento relacionado con la configuración del origen de datos bajo esa subclave; otro método es crear un nuevo proyecto bajo la subclave \ODBC. INI\ODBC Data Source le indica al administrador del controlador el tipo de fuente de datos ODBC. A continuación se toma la configuración de la fuente de datos de Microsoft Access como ejemplo para brindar el código de función para implementar esta función.
/* strSourceName es el nombre de la fuente de datos que se creará, strSourceDb es la ruta de almacenamiento de la base de datos y strDescription es la cadena de descripción de la fuente de datos. */
BOOL CLoadOdbcDlg::LoadDbSource(c string strsource name, CString strSourceDb, CString strDescription)
{
//Almacenamiento clave de registro abierta
HKEY hKey;
DWORD dw
//Almacena el valor de retorno de la ejecución de la función API del registro.
LONG lReturn
//Almacena el subelemento que se va a abrir.
CString strSubKey
//Compruebe si el controlador ODBC de MS Access: odbcjt32.dll está instalado.
//Obtener el directorio del sistema de Windows
char sysDir[MAX _ PATH];
char drv name[]= " \ \ odbcjt 32. dll "
* obtener el directorio del sistema(sysDir, MAX_PATH);
strcat(sysDir, drvName);
CFileFind findFile
If ( !Buscar archivo.
FindFile (sysDir))
{
AfxMessageBox ("odbcjt32.dll, el controlador ODBC para MS Access, no está instalado en su sistema informático, por lo que no podrá cargar este origen de datos.", MB_OK | MB_ICONSTOP);
Devuelve falso
}
str subkey = "SOFTWARE\\ODBC\\ODBC INI \ \ ". strSourceName;
//Crea una subclave de la fuente de datos ODBC en el registro.
lReturn =::RegCreateKeyEx(HKEY_LOCAL_
MACHINE, (LPCTSTR)strSubKey, 0, NULL, REG_OPTION
_NON_VOLATILE, KEY_WRITE, NULL, hKey, dw) ;
if(lReturn!=Error_success)
Devuelve falso
//Establece varios parámetros de la fuente de datos.
CString strDbq = strSourceDb
CString strDriver = sysDir
DWORD dwDriverId = 25
CString strFil = " MS Access
CString strPwd = strSourceName
DWORD dwSafeTransactions = 0;
CString strUid = strSourceName
* RegSetValueEx(hKey, "DBQ", 0L, REG_SZ,
(CONST BYTE*)((LPCTSTR) strDbq), strDbq.GetLength()); * RegSetValueEx(hKey, "Descripción", 0L, REG_SZ, (CONST BYTE *)((LPCTSTR)strDescripción) , str Descripción.GetLength());
* RegSetValueEx(hKey, "Driver", 0L, REG_SZ, (CONST BYTE* )((LPCTSTR)strDriver), strDriver.GetLength()); p> p>
* RegSetValueEx(hKey, " DriverId ", 0L, REG_DWORD, (CONST BYTE* )( dwDriverId), sizeof(dw));
* RegSetValueEx(hKey, " FIL " , 0L , REG_SZ,
(CONST BYTE* )((LPCTSTR) strFil), strGetLength()); ,
(CONST BYTE* )((LPCTSTR)strPwd), strPwd.
GetLength()); * RegSetValueEx(hKey, "transacciones seguras", 0L,
REG_DWORD, (CONST BYTE *)(dw transacciones seguras), sizeof(dw)); * RegSetValueEx(hKey, "UID", 0L, REG_SZ,
(CONST BYTE* )((LPCTSTR)strUid), strUid.GetLength()); p>//Cree el subelemento Jet de la fuente de datos ODBC.
str subkey = "\\Engines\\Jet";
lReturn =::RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPCTSTR)strSubKey, 0, NULL, REG_OPTION_NON_ p>
VOLATILE, KEY_WRITE, NULL, hKey, dw);
if (lReturn! = error_success)
Devuelve false
// Establece los parámetros bajo esta subclave .
CString strImplict =
CString strUserCommit = " Sí
Tiempo de espera de página DWORD dw = 5;
Subprocesos DWORD dw = 3;
DWORD dwMaxBufferSize = 2048
* RegSetValueEx(hKey, "ImplictCommitSync", 0L, REG_SZ, (CONST BYTE *)((LPCTSTR)strImplict), strImplict. GetLength() 1);
* RegSetValueEx(hKey, " MaxBufferSize ", 0L, REG_DWORD, (CONST BYTE* )( dwMaxBufferSize), sizeof(dw));
* RegSetValueEx(hKey, " PageTimeout "). , 0L, REG_DWORD, (CONST BYTE* )( dwPageTimeout), sizeof(dw));
* RegSetValueEx(hKey, "Threads", 0L, REG_DWORD, (CONST BYTE* )( dwThreads), sizeof (dw));
* RegSetValueEx(hKey, "UserCommitSync", 0L, REG_SZ, (CONST BYTE *)((LPCTSTR)strUserCommit), confirmación de struser. GetLength());
* RegCloseKey(hKey);
//Establecer el nombre del motor de base de datos ODBC
lReturn =:: RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\ODBC\\ODBC.
INI\\ODBC Data Source", 0L, KEY_WRITE, hKey);
if (lReturn! = error_success)
Devuelve false
c cadena strDbType = " Controlador de Microsoft Access (*.MDB)"; *RegSetValueEx(hKey,strSourceName,0L,REG_SZ,(CONST BYTE*)((LCTSTR)strDbType),strDbType.GetLength());
Devuelve verdadero
}
Debido a que en la carga dinámica, generalmente solo se cambian el archivo de la base de datos, la descripción de la fuente de datos y la descripción de la fuente de datos, las funciones anteriores pueden satisfacer la mayoría de las necesidades de la aplicación. Se necesitan más cambios en la aplicación, también se puede lograr cambiando los parámetros de la función. Para la carga dinámica de múltiples tipos de fuentes de datos, se pueden usar funciones sobrecargadas con diferentes parámetros.
Método 2: Uso. DLL
Concepto de diseño
La biblioteca de enlaces dinámicos Odbcinst.dll en el subdirectorio del sistema de Windows proporciona una función SQLConfigDataSource (), que puede agregar, modificar y eliminar dinámicamente fuentes de datos El prototipo. es el siguiente:
BOOL SQLConfigDataSource(HWND HWND parent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes);
El parámetro hwndParent es el identificador de la ventana principal. Si el valor es NULL, no lo hará. Muestra un cuadro de diálogo relacionado con la ventana principal.
El parámetro fRequest se puede configurar en uno de los siguientes valores:
ODBC_ADD_DSN: agrega una nueva fuente de datos de usuario;
ODBC_CONFIG_DSN: Modificar (configurar) fuentes de datos de usuario existentes;
ODBC_REMOVE_DSN: Eliminar fuentes de datos de usuario existentes;
ODBC_ADD_SYS_DSN: Agregar nuevas fuentes de datos del sistema; p>
ODBC_CONFIG_SYS_DSN: Modificar (configurar) la fuente de datos del sistema existente
ODBC_REMOVE_SYS_DSN: Eliminar la fuente de datos del sistema existente
El parámetro lpszDriver se utiliza para pasar el nombre del motor de base de datos, que es equivalente a la variable strDbType en el método 1.
El parámetro lpszAttirbutes es el valor de la palabra clave, es decir, una serie de cadenas "keyname=value", separadas por "\" entre ellas. cada dos cadenas, como DSN = datos de personal \ 0 uid = Smith \ 0 base de datos = personal. Para obtener configuraciones detalladas de este parámetro, consulte la documentación de ayuda de la función SQLConfigDataSource() en MSDN y diversa documentación del controlador ODBC.
Implementación específica
Dado que el archivo de biblioteca VC predeterminado no contiene la función SQLConfigDataSource(), antes de usar esta función, debe incluir el archivo odbcinst.h en el archivo de encabezado de el proyecto. Agregue odbc32.lib en el cuadro de edición del módulo de objeto/biblioteca en la página de propiedades del enlace del cuadro de diálogo Propiedades de configuración del proyecto y asegúrese de que exista el archivo odbccp32.dll en el directorio del sistema system32.
Aún tomando Microsoft Access como ejemplo, configure la fuente de datos en demostración, configure la fuente de datos en "Fuente de datos de muestra" y luego agregue el siguiente código donde la fuente de datos debe cargarse dinámicamente:
* sqlconfigdatasource(null, odbc_add_sys_DSN, "Microsoft Access Driver (*.MDB)", "DSN=demo\0 descripción=base de datos de muestra");
Resumen
p >Los dos métodos anteriores pueden cargar dinámicamente varios tipos de fuentes de datos ODBC y han sido depurados en el entorno Windows95/98/NT/2000. El primer método requiere más código para implementar y el segundo método requiere menos código pero requiere el soporte de archivos adicionales. Y a medida que aumenta la flexibilidad de la configuración del origen de datos, la longitud del código para formar la cadena lpszAttributes también aumentará en consecuencia. Debido a que configurar la fuente de datos desde el panel de control puede brindar a los programadores una comprensión más intuitiva, los programadores no solo pueden verificar la documentación del controlador relevante, sino también configurar la fuente de datos ODBC a través del panel de control antes de programar y luego proceder de acuerdo con el contenido del parte correspondiente del registro.
=======================================
Crear dinámicamente el nombre de la fuente de datos de Access
Este artículo está escrito por Madawa v.
El ejemplo de este artículo se creó utilizando VC 5.0. Necesario. mano. El archivo lib existe en el zip.
Para crear un DSN en tiempo de ejecución, puede utilizar la API SQLConfigDataSource. Internamente, esta información se almacena en el registro. La sintaxis se adjunta a continuación
SQLConfigDataSource(NULL, ODBC_ADD_DSN, "Microsoft Access Driver (*.mdb)\0", "DSN=TestDB\0 dbq=D:\\Database\\friends.MDB\ 0 default dir = D:\\Database\0\0");
El problema es si desea aceptar valores del usuario o establecer estos valores en tiempo de ejecución pasando CString o char* es la línea No tiene sentido. Esto se debe a que, cuando sprintf encuentra /0, asume que es el final de la cadena e ignora el resto de los datos.
Como solución alternativa, debe utilizar el código que se menciona a continuación.
El siguiente código pone : donde debería estar /0 y tiene un bucle que reemplaza ":" por "/0". No podrás usar sprintf porque cuando encuentra /0 asume que es el final de la cadena e ignora el resto de los datos.
char * szDesc
int mlen
szDesc = new char[256];
sprintf(szDesc, "DSN=s: DESCRIPTION=TOC Fuente de soporte: DBQ=s:FIL=Microsoft access:default dir=D:\\Database::","TestDB","D:\\friends.MDB");
mlen = strlen(szDesc);
for(int I = 0; iltmleni)
{
if (szDesc[i] == ':')
szDesc[I] = '\0';
}
if(FALSE == SQLConfigDataSource(NULL,ODBC_ADD_DSN," Controlador Microsoft Access (*. mdb )\0 ", (LPCSTR)szDesc))
MessageBox(hwnd, "Failure", "Message", MB_OK);
Otro
MessageBox( hwnd, "Éxito", "Mensaje", MB_OK);