调用ImpersonateLoggedOnUser后无法通过用户DSN连接Phoenix ODBC驱动求助
解决ImpersonateLoggedOnUser后Phoenix ODBC无法找到DSN的问题
这个问题我之前碰到过,核心原因是模拟用户后,进程的上下文切换到了被模拟用户的环境,而原有的DSN配置可能只对原用户可见。下面分几个方向给你解决思路:
1. 将用户DSN切换为系统DSN
ODBC的DSN分为两种:
- 用户DSN:仅对当前登录用户可见,存储在用户注册表分支(
HKEY_CURRENT_USER\Software\ODBC\ODBC.INI) - 系统DSN:对所有用户(包括模拟用户)可见,存储在系统注册表分支(
HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI)
你之前能用特定用户访问,大概率是配置了用户DSN。切换成系统DSN的步骤:
- 注意区分32位/64位程序:如果你的程序是32位,打开
C:\Windows\SysWOW64\odbcad32.exe;64位则打开C:\Windows\System32\odbcad32.exe - 切换到「系统DSN」标签页,添加对应的Apache Phoenix ODBC驱动配置,参数和原来的用户DSN保持一致
- 测试模拟用户后调用
SQLDriverConnect,应该就能找到DSN了
2. 直接使用无DSN的连接字符串
如果不想改DSN配置,可以跳过DSN,直接在代码里写完整的连接字符串,绕过ODBC管理器的DSN查找逻辑。示例连接字符串大概是这样:
SQLDriverConnect(hdbc, NULL, (SQLCHAR*)"DRIVER={Apache Phoenix ODBC Driver};HOST=your-phoenix-host;PORT=8765;AUTHENTICATION=BASIC;USER=username;PASSWORD=password;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
具体参数根据你的Phoenix集群配置调整,这样不管用户上下文是什么,只要驱动存在就能连接。
3. 检查驱动位数与程序位数匹配
很多人会忽略这个点:32位程序只能加载32位的ODBC驱动,64位同理。如果你的程序是32位,但你在64位的ODBC管理器里配置了系统DSN,那32位程序是看不到的。一定要确保:
- 程序位数 → 对应位数的ODBC管理器 → 配置对应位数的驱动
4. 确保被模拟用户有驱动访问权限
被模拟的用户可能没有权限读取Phoenix ODBC驱动的安装目录或注册表项:
- 找到驱动的安装文件夹(比如
C:\Program Files\Apache Phoenix ODBC Driver),给被模拟用户添加「读取&执行」权限 - 打开注册表编辑器,找到
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\Apache Phoenix ODBC Driver,给被模拟用户添加读取权限
另外,代码里调用ImpersonateLoggedOnUser后,如果数据库操作完成,记得调用RevertToSelf()恢复原用户上下文,避免后续操作出现权限问题。
内容的提问来源于stack exchange,提问作者Pratik Borhade
相关产品推荐
相关产品推荐

