使用OpenRowSet时如何指定返回结果的字段排序规则?
解决方案
一、让OPENROWSET返回指定排序规则的结果
你可以在OPENROWSET执行的存储过程调用外层,对返回的字符型字段显式指定目标排序规则,这样SELECT * INTO创建的表就会继承正确的排序规则。
比如目标数据库排序规则为Chinese_PRC_CI_AS,修改代码如下:
SELECT Col1 COLLATE Chinese_PRC_CI_AS AS Col1, Col2 COLLATE Chinese_PRC_CI_AS AS Col2, -- 非字符型字段直接保留,其他字符字段依次处理 Col3, Col4 INTO dbo.table1 FROM OPENROWSET('SQLNCLI', 'Server=(local);Trusted_Connection=yes;', 'EXEC DB.[dbo].Procedure1') AS procResult
注意:必须明确列出存储过程返回的所有字段,不能使用*,这样才能对每个字符字段指定排序规则。如果字段较多,可先单独执行一次存储过程获取完整字段列表后再编写查询。
若你有修改存储过程的权限,也可以直接在存储过程内部,让返回的字符字段使用目标数据库的排序规则,从源头解决问题。
二、替换OPENROWSET的可行方案
如果不想依赖OPENROWSET,以下两种方法同样能实现需求:
1. 临时表+INSERT INTO(推荐)
先显式创建匹配存储过程返回结构的表(指定正确排序规则),再执行存储过程插入数据:
-- 先创建表,明确指定每个字符字段的排序规则 CREATE TABLE dbo.table1 ( Col1 VARCHAR(50) COLLATE Chinese_PRC_CI_AS, Col2 NVARCHAR(100) COLLATE Chinese_PRC_CI_AS, Col3 INT, Col4 DATETIME ) -- 执行存储过程插入数据 INSERT INTO dbo.table1 EXEC DB.[dbo].Procedure1
这种方法完全可控,不需要OPENROWSET,创建表时直接指定排序规则即可规避权限问题。
2. 使用OPENQUERY(需服务器配置支持)
若服务器已启用Ad Hoc Distributed Queries且配置了本地链接服务器,可通过OPENQUERY执行存储过程并转换排序规则:
SELECT Col1 COLLATE Chinese_PRC_CI_AS AS Col1, Col2 COLLATE Chinese_PRC_CI_AS AS Col2, Col3, Col4 INTO dbo.table1 FROM OPENQUERY(LOCAL_SERVER, 'EXEC DB.[dbo].Procedure1') AS procResult
这里的LOCAL_SERVER是预先配置好的指向本地服务器的链接服务器。
三、关键注意事项
- 避免用
SELECT * INTO创建表,因为它会默认继承源数据的排序规则,显式创建表并指定排序规则是更可靠的方式。 - 如果无法修改现有表的排序规则,确保后续视图中涉及字符字段的操作都显式指定排序规则,比如在视图查询中添加
COLLATE子句,彻底避免排序规则冲突报错。
内容的提问来源于stack exchange,提问作者DEV123
相关产品推荐
相关产品推荐

