EXEC(查询)AT linkedServer与Oracle DB

时间:2009-02-27 15:59:47

标签: sql sql-server oracle

我正在使用Microsoft SQL Server 2005.我需要在SQL服务器和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中使用google示例。我能找到的只有SQL或ExpressSQL衬里的服务器示例如:

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项目来完成这项工作。在此之前,我只是想知道是否有任何方法可以将值作为oupput参数传递出去,以便在我的SP中放置性能更好的T-SQL代码?

2 个答案:

答案 0 :(得分:3)

快速更新一下。我想我得到了解决方案。我在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 

娲!我在3秒内得到了结果,直接在Orable DB上比较T-SQL查询(+ 2分钟)。重要的是使用“BEGIN”和“END;”将查询包装为匿名块,不要错过“;”在END之后

您需要匿名阻止输出参数。如果您只有输入或没有参数,则不需要块,查询工作正常。

享受吧!顺便说一句,这是一个快速更新。如果你再也没有见到我,我就不会遇到这个问题。

答案 1 :(得分:0)

使用Linked Services,最大的问题是性能(恕我直言) [linkedserver]...[dbo.RemoteTable] vs OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable') 始终使用第二个

现在回答这个问题。 OPENQUERYEXEC() AT要快得多。 EXEC(Select * from dbo.RemoteTable) AT linkedserver会显示结果,但无法重复使用。

我的简单解决方案:

SELECT * INTO LocalTable FROM OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')

OR

INSERT INTO LocalTable SELECT * FROM OPENQUERY(linkedserver, 'Select * from dbo.RemoteTable')

更快^ 10
SELECT * INTO LocalTable FROM [linkedserver]...[dbo.RemoteTable]