在我的Windows框中,我可以列出用户和系统ODBC dsns。例如:
在我的代码中,我可以使用数据源的名称连接到数据库。例如:
QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
db.setDatabaseName("M10-Server-Production");
我想获取用户和系统的数据源名称列表,过滤它们以仅包含适合我的应用程序的名称,在此示例中,它们将以“M10-Server”开头,然后将列表提供给用户可以选择要连接的数据库。
如何以编程方式获取DSN列表?
注意:该应用程序可以在Windows或Linux上运行,因此欢迎使用其中一种或两种的解决方案。
答案 0 :(得分:2)
在Windows上,您可以使用函数SQLDataSources
列出系统上配置的可用系统和/或用户DSN。有关详细信息,请参阅此处:https://msdn.microsoft.com/en-us/library/ms711004%28v=vs.85%29.aspx
unixodbc也提供此功能,但我从未使用过unixodbc。
在Windows上执行此操作的一些可编译和可用的示例代码:
#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <sql.h>
#include <sqlext.h>
#include <sqlucode.h>
#define BUFF_LENGTH 1024
int _tmain(int argc, _TCHAR* argv[])
{
// Get an Environment handle
SQLHENV hEnv = SQL_NULL_HENV;
// SQLAllocHandle() is for ODBC 3.x
SQLRETURN ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
// If you do not have ODBC 3.x try with the old version:
// SQLRETURN ret = SQLAllocEnv(&hEnv);
if(!SQL_SUCCEEDED(ret))
{
std::wcerr << L"No handle" << std::endl;
return 1;
}
// set odbc version (this is required, if not set we get 'function sequence error')
ret = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3_80, NULL);
if(!SQL_SUCCEEDED(ret))
{
std::wcerr << L"Failed to set version" << std::endl;
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
return 1;
}
// Query sources
SQLWCHAR nameBuffer[BUFF_LENGTH];
SQLWCHAR descBuffer[BUFF_LENGTH];
SQLSMALLINT nameBufferLength = 0;
SQLSMALLINT descBufferLength = 0;
ret = SQLDataSources(hEnv, SQL_FETCH_FIRST, nameBuffer, BUFF_LENGTH, &nameBufferLength, descBuffer, BUFF_LENGTH, &descBufferLength);
if(ret == SQL_NO_DATA)
{
// no entries found
std::wcout << L"No DSN found" << std::endl;
}
else if(SQL_SUCCEEDED(ret))
{
do
{
// do something with the name available in nameBuffer now..
std::wcerr << L"Name: " << nameBuffer << std::endl;
// then fetch the next record
ret = SQLDataSources(hEnv, SQL_FETCH_NEXT, nameBuffer, BUFF_LENGTH, &nameBufferLength, descBuffer, BUFF_LENGTH, &descBufferLength);
} while(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO);
}
else
{
SQLSMALLINT recNr = 1;
SQLRETURN ret = SQL_SUCCESS;
while(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
SQLWCHAR errMsg[SQL_MAX_MESSAGE_LENGTH + 1];
SQLWCHAR sqlState[5 + 1];
errMsg[0] = 0;
SQLINTEGER nativeError;
SQLSMALLINT cb = 0;
ret = SQLGetDiagRec(SQL_HANDLE_ENV, hEnv, recNr, sqlState, &nativeError, errMsg, SQL_MAX_MESSAGE_LENGTH + 1, &cb);
if(ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
std::wcerr << L"ERROR; native: " << nativeError << L"; state: " << sqlState << L"; msg: " << errMsg << std::endl;
}
++recNr;
}
std::wcerr << L"Failed";
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
return 1;
}
SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
return 0;
}
将SQL_FETCH_FIRST
替换为SQL_FETCH_FIRST_USER
或SQL_FETCH_FIRST_SYSTEM
,以仅获取用户或系统dsn条目。
请注意,您需要在构建应用时链接odbc32.lib
。