我正在使用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代码?
答案 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')
始终使用第二个
现在回答这个问题。 OPENQUERY
和EXEC() 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')
比
更快^ 10SELECT * INTO LocalTable FROM [linkedserver]...[dbo.RemoteTable]