EXEC(query) AT linkedServer 与 Oracle DB
Posted
技术标签:
【中文标题】EXEC(query) AT linkedServer 与 Oracle DB【英文标题】:EXEC(query) AT linkedServer With Oracle DB 【发布时间】:2009-02-27 15:59:46 【问题描述】:我使用的是 Microsoft SQL Server 2005。我需要在 SQL Server 和 Oracle 数据库之间同步数据。我需要的第一件事是找出Oracle端的数据计数是否带有某些过滤器(这里我使用ID作为一个简单的例子)。
SELECT COUNT(*) FROM oracleServer..owner.table1 WHERE id = @id;
我遇到的问题是内衬服务器或 Oracle 上的表非常大,有 4M 行数据。上述查询大约需要 2 分钟才能取回数据。这段代码只是一个简单的部分。实际上,我的 SP 有一些其他查询要更新,将数据从内衬服务器插入到我的 SQL 服务器。 SP 需要数小时或 10 多个小时才能运行大型 Oracle 数据库。因此带有内衬服务器的 T-SQL 对我来说并不好。
最近我发现 OPENQUERY 和 EXEC (...) AT linedServer。 OPENQUERY() 非常快。获得相同结果大约需要 0 时间。但是,它不支持变量查询或表达式。查询必须是文字常量字符串。
EXEC() 与将查询传递给 Oracle 的方式相同。它也很快。例如:
EXEC ('SELECT COUNT(*) FROM owner.table1 WHERE id = ' + CAST(@id AS VARCHAR))
AT oracleServer
我遇到的问题是如何将结果 COUNT(*) 传回。我尝试在 web 和 msdn 中搜索示例。我能找到的只是 SQL 或 ExpressSQL linedServer 示例,例如:
EXEC ('SELECT ? = COUNT(*) FROM ...', @myCount OUTPUT) AT expressSQL
此查询不适用于 Oracle。在 Oracle 中,您可以通过这种方式将值设置为输出:
SELECT COUNT(*) INTO myCount ...
我试过了:
EXEC ('SELECT COUNT(*) INTO ? FROM ...', @myCount OUTPUT) AT oracleServer
EXEC ('SELECT COUNT(*) INTO : FROM ...', @myCount OUTPUT) AT oracleServer
EXEC ('SELECT : = COUNT(*) FROM ...', @myCount OUTPUT) AT oracleServer
这些都没有工作。我收到错误消息说查询在 Oracle 服务器上不可执行。
我可以编写一个 .Net SQL Server 项目来完成这项工作。在此之前,我只是想知道是否有办法将值作为输出参数传递出去,以便我将性能更好的 T-SQL 代码放在我的 SP 中?
【问题讨论】:
【参考方案1】:只是对此的快速更新。我想我得到了解决方案。我在Dev NewsGroup 上关于类似问题的讨论中找到了它。根据信息,我尝试了这个:
DECLARE @myCount int;
DECLARE @sql nvarchar(max);
set @sql =
N'BEGIN
select count(*) into :myCount from DATAPARC.CTC_MANUAL_DATA;
END;'
EXEC (@sql, @myCount OUTPUT) AT oracleServer;
PRINT @myCount; -- 3393065
哇!直接在 Orable DB 上比较 T-SQL 查询,我在 3 秒内得到了结果(+2 分钟)。重要的是使用“BEGIN”和“END;”将查询包装为匿名块,不要错过“;”结束后
您需要匿名块作为输出参数。如果您只有输入或没有参数,则不需要该块并且查询可以正常工作。
尽情享受吧!顺便说一句,这是一个快速更新。如果你再也见不到我,我不会在这个问题上遇到任何麻烦。
【讨论】:
最近我发现这个方法有一个有趣的问题。我已经在我的沼泽中发布了有关使用 Exec() At Continued (davidchuprogramming.blogspot.com/2009/03/…) 的详细信息。【参考方案2】:对于链接服务,最大的问题是性能(恕我直言)
[linkedserver]...[dbo.RemoteTable] vs OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')
总是使用第二个
现在回答这个问题。 OPENQUERY
和 EXEC() AT
更快。
EXEC(Select * from dbo.RemoteTable) AT linkedserver
会显示结果,但是没有办法重复使用。
我的简单解决方案:
SELECT * INTO LocalTable FROM OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')
或
INSERT INTO LocalTable SELECT * FROM OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')
比
快得多 ^10SELECT * INTO LocalTable FROM [linkedserver]...[dbo.RemoteTable]
【讨论】:
以上是关于EXEC(query) AT linkedServer 与 Oracle DB的主要内容,如果未能解决你的问题,请参考以下文章
使用 query_exec() 时 bigrquery 抛出“错误:无效凭据”
使用 SQL Server 2000 插入 @TABLE EXEC @query
SQL sys.dm_exec_query_stats Last_Elapsed_Time 废话
在QT中用 QSqlQuery query;查询, 第一次 query.exec();结果是对的,可是第二次执行的时候读的数据是错的