使用OPENROWSET读取Excel时出现DBSCHEMA_TABLES_INFO错误及SQL崩溃问题
- 环境:Windows 10 Pro 64位、SQL Server 2017 Developer Edition(RTM-CU30)64位、Office Professional Plus 2016 64位
- 操作:创建含简单数据的Excel工作簿并保存为
C:\Book1.xlsx,通过SSMS 18执行以下查询:SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0 Xml;Database=C:\Book1.xlsx', [Sheet1$]) - 错误情况:
- 禁用
Microsoft.ACE.OLEDB.12.0的AllowInProcess选项时:Msg 7399, Level 16, State 1, Line 1
The OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7311, Level 16, State 2, Line 1
Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)". The provider supports the interface, but returns a failure code when it is used.
(Process Monitor显示dllhost.exe可读取文件,排除配置或权限问题) - 启用
AllowInProcess选项时,SQL Server崩溃(sqlservr.exe意外终止):Msg 109, Level 20, State 0, Line 0
A transport-level error has occurred when receiving results from the server. (provider: Shared Memory Provider, error: 0 - The pipe has been ended.) - 替换为
Microsoft.ACE.OLEDB.16.0后错误相同,但64位导入导出数据向导可正常运行。
- 禁用
核心原因
问题根源是64位SQL Server与ACE OLEDB Provider的进程内/进程外兼容性冲突,以及Office自带ACE组件与SQL Server运行环境的二进制不兼容:
- 禁用
AllowInProcess时,ACE Provider在独立的dllhost.exe进程中运行,虽然文件读取正常,但SQL Server请求元数据(DBSCHEMA_TABLES_INFO)时,进程间通信的兼容性问题导致报错。 - 启用
AllowInProcess时,ACE Provider直接加载到sqlservr.exe进程内,Office 2016的ACE组件与SQL Server 2017依赖的运行库、COM接口存在冲突,直接触发SQL Server进程崩溃。 - 导入导出向导正常是因为它是独立进程,单独加载ACE组件,不与SQL Server进程共享内存空间,规避了冲突。
可行解决方法
- 方法一:改用SSIS包替代OPENROWSET
既然导入导出向导可正常工作,可将向导配置保存为SSIS包,按需手动执行或通过SQL Server Agent调度,这是最稳定的替代方案。 - 方法二:优化OPENROWSET连接字符串
添加HDR=YES;IMEX=1参数,强制解析表头并将混合数据类型统一为文本,避免元数据解析错误:
注意:此方法仅解决部分元数据问题,启用SELECT * FROM OPENROWSET('Microsoft.ACE.OLEDB.16.0', 'Excel 12.0 Xml;HDR=YES;IMEX=1;Database=C:\Book1.xlsx', [Sheet1$])AllowInProcess后仍可能出现进程崩溃,需测试验证。 - 方法三:重新安装独立版ACE组件
卸载Office自带的ACE组件,单独安装Microsoft Access Database Engine 2016 Redistributable(64位),安装时使用被动模式命令行避免与Office冲突:
安装完成后重新配置ACE Provider的AccessDatabaseEngine_X64.exe /quietAllowInProcess选项,再测试OPENROWSET查询。 - 方法四:改用Linked Server
配置Linked Server指向Excel文件,指定ACE Provider并设置数据源为C:\Book1.xlsx,调整Provider选项(如禁用AllowInProcess后开启Dynamic Parameters)。Linked Server的元数据处理逻辑与OPENROWSET不同,可能绕过部分兼容性错误。
内容的提问来源于stack exchange,提问作者Michael Liu

