从没有分布式事务的非常大的 OPENQUERY 中插入结果

Inserting results from a very large OPENQUERY without distributed transactions

我正在尝试从命中链接的 Oracle 11g 服务器的查询中将行插入 Microsoft SQL Server 2014 table。我在链接服务器上拥有只读访问权限。我传统上使用 OPENQUERY 来做如下事情:

INSERT INTO <TABLE> SELECT * FROM OPENQUERY(LINKED_SERVER, <SQL>)

随着时间的推移,我 运行 的 SQL 查询变得越来越复杂,最近超过了 OPENQUERY 8000 个字符的限制。网络上的普遍共识似乎是切换到如下内容:

INSERT INTO <TABLE> EXECUTE(<SQL>) AT LINKED_SERVER

但是,这似乎需要在链接服务器上启用分布式事务,这不是本项目的选项。我还缺少其他可能的解决方案吗?

如果 SQL 服务器集成服务是 installed/available,您可以使用 SSIS 包执行此操作。 SQL 服务器 Import/Export 向导可以为您自动完成很多包 configuration/setup。

这是上一个问题,其中包含一些有用的 SSIS 到 Oracle 的链接:

Connecting to Oracle Database using Sql Server Integration Services

如果您通过 T-SQL 对 运行 它感兴趣,这里有一篇关于从存储过程执行 SSIS 包的文章:

http://www.databasejournal.com/features/mssql/executing-a-ssis-package-from-stored-procedure-in-sql-server.html

我以前遇到过类似的情况,对我有用的是分解大查询字符串,同时仍然使用下面的查询方法。 (我没有 SSIS 的奢侈)。

FROM OPENQUERY(LINKED_SERVER, < SQL >) 
  1. 与其直接插入 table,不如先将主要结果集移动到本地临时登陆点 table(可以是物理的或临时的 table)。
  2. 通过将转换和业务逻辑代码移动到 < SQL > 查询之外的 SQL 服务器边界来分解您的 < SQL > 查询。
  3. 如果您在 < SQL > 查询中加入了这些结果集,也将这些结果集传送到 SQL 服务器,然后在本地加入到您的主要结果集。
  4. 最后在本地执行插入。
  5. 清理您的暂存区。

有多种方法(例如将打开的查询包装在视图中),但我喜欢灵活性,并且发现将打开的查询的大小减少到最小,在本地存储和转换会产生更好的结果。

希望对您有所帮助。

如果您禁用 "remote proc transaction promotion" 链接服务器选项,您能否使用第二种方法?

EXEC master.dbo.sp_serveroption
    @server = 'YourLinkedServerName',
    @optname = 'remote proc transaction promotion',
    @optvalue = 'false'