通过OpenDataSource/OpenRowSet读取Excel时,行序能否与Excel物理行一致?
读取Excel至临时表时,能否保证id与物理行序完全一致?
原问题代码
INSERT INTO #MyTable (id, F1) SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS id, F1 FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.16.0','Data Source=FilePathMustBeHere; Extended Properties="EXCEL 12.0;HDR=No;IMEX=1"')...['SheetNameMustBeHere$']
核心结论
无法100%保证#MyTable的id值与Excel物理行序完全一致,原因如下:
ORDER BY (SELECT 1)只是为了满足ROW_NUMBER()的语法要求,并非真的按物理行序排序。SQL Server处理无明确排序的查询时,返回行的顺序依赖于执行计划、存储引擎临时逻辑,没有固定规则。- 底层的Microsoft ACE OLEDB驱动读取Excel时,本身不保证返回行的物理顺序。Excel的存储结构并非关系型表,驱动读取时可能受单元格格式、隐藏行、空值分布等因素影响,行序没有可靠稳定性。
可行替代方案
方案1:修改Excel文件添加行号
在Excel中手动插入一列(如A列),从1开始填充连续序号,读取时按该列排序生成id,示例代码:
INSERT INTO #MyTable (id, F1) SELECT CAST(F1 AS INT) AS id, F2 FROM OPENDATASOURCE('Microsoft.ACE.OLEDB.16.0','Data Source=FilePathMustBeHere; Extended Properties="EXCEL 12.0;HDR=No;IMEX=1"')...['SheetNameMustBeHere$'] ORDER BY F1;
方案2:使用SSIS读取
若无法修改原Excel,可借助SSIS的Excel数据源组件:
- SSIS默认配置下读取Excel的逻辑更贴近物理行序
- 添加「脚本组件」作为转换,在脚本中生成自增行号,最终写入临时表或目标表,稳定性远高于T-SQL直接读取
内容的提问来源于stack exchange,提问作者Victor Sotnikov
相关产品推荐
相关产品推荐

