Tsql SQL Server OpenQuery()的行为与TOAD的直接查询不同

Tsql SQL Server OpenQuery()的行为与TOAD的直接查询不同,tsql,sql-server-2008-r2,oracle11g,toad,openquery,Tsql,Sql Server 2008 R2,Oracle11g,Toad,Openquery,使用TOAD(使用本机Oracle驱动程序)直接对Oracle 11运行时,以下查询工作效率很高 如果通过openquery()从SQL Server 2008传递到同一Oracle数据库,则完全相同的查询“从不”返回。SQL Server使用Oracle提供程序OLE DB驱动程序链接到Oracle数据库 select * from openquery( servername, ' select ... from ... where ... and srvg_ocd in (

使用TOAD(使用本机Oracle驱动程序)直接对Oracle 11运行时,以下查询工作效率很高

如果通过
openquery()
从SQL Server 2008传递到同一Oracle数据库,则完全相同的查询“从不”返回。SQL Server使用Oracle提供程序OLE DB驱动程序链接到Oracle数据库

select * from openquery( servername, '
  select ... from ... where ...
  and srvg_ocd in (
    select ocd
     from rptofc
    where eff_endt = to_date(''12/31/9999'',''mm/dd/yyyy'')
      and rgn_nm = ''Boston''
  ) ...
');
查询没有在合理的时间内返回,用户将终止查询。我不知道它是否最终会返回正确的结果

直接蟾蜍查询有效且
openquery()
version“never”返回的结果是可复制的

openquery()
进行一个小的修改可以得到正确的有效结果:将
eff\u endt
更改为
trunc(eff\u endt)

这很好,但似乎没有必要改变

openquery()
应该是传递的,那么蟾蜍和
openquery()
行为之间有什么区别呢?

我们之所以关心这个问题,是因为我们经常开发复杂的查询,TOAD直接访问Oracle。查询运行并优化后,我们将其转换为
openquery()
字符串,以便在SQL Server应用程序中使用。当我们知道查询作为直接查询工作时,使用
openquery()
突然失败是非常令人恼火的。然后,我们必须通过反复试验寻找解决办法

我想查看这两个场景的Oracle跟踪文件,但Oracle服务器位于另一个组织中,我们没有得到Oracle DBA的合作


有人知道有司机、蟾蜍或???可能导致差异的问题?有没有办法消除这个问题,使两种方法都能得到相同的结果?

我知道你刚才问了这个问题,但我刚刚遇到了你的问题

我同意,它们应该是一样的。显然有区别。我们需要找出区别在哪里

当我打字时,我在大声思考

如果只指定几列而不是从openquery中选择*会发生什么

应该返回多少行

如果在oracle select中限制返回的行,会怎么样

openquery超时的速度有多快

蟾蜍和SS在同一台机器上吗?你是不是要撞上党卫军,然后从那里跑掉蟾蜍

他们使用相同的驱动程序吗?包括比特?(32/64)版本

他们在oracle上使用相同的帐户吗

有趣的是,使用
trunc()
会有所不同。我假设[eff_endt]是返回的字段之一

我想知道SS是不是把所有的行都拿回来了,但是它在做日期转换时被卡住了。oracle中的日期类型可能需要转换为ss日期类型,然后ss才会显示给您

如果将openquery中的行插入到一个表中,其中日期字段只是一个
(n)varchar
,该怎么办。我想ss可能只是将它从oracle返回的日期转储到该文本字段中,而不尝试转换它

比如:

insert into mytable(f1,f2,f3,datetimeX)
select f1,f2,f3,datetimeX from openquery( servername, '
  select f1,f2,f3,datetimeX from ... where ...
  and srvg_ocd in (
    select ocd
     from rptofc
    where eff_endt = to_date(''12/31/9999'',''mm/dd/yyyy'')
      and rgn_nm = ''Boston''
  ) ...
');
如果toad或ss在将查询语句发送到oracle之前修改查询语句,该怎么办。你可以启动wireshark,看看蟾蜍和党卫军到底在发送什么


如果你能解决这个问题,我会很好奇的。我经常将ss链接到oracle,但没有遇到过这个问题。

以下是一些基本的东西,您可以检查一下,看看数据库在收到查询后正在做什么。首先,检查TOAD中的执行计划是否与使用openquery运行查询时相同。您可以使用以下方法在TOAD中自己规划查询:

explain plan set statement_id = 'openquery_test' for <your query here>;

select *
from table(dbms_xplan.display(statement_id => 'openquery_test';
explain plan set statement\u id='openquery\u test'for;
挑选*
从表(dbms_xplan.display)(语句_id=>openquery_test);
然后让某人使用openquery()启动查询,并让某人具有查看要运行的v$表的权限:

select sql_id from v$session where username = '<user running the query>';
从v$session中选择sql\u id,其中username='';
(如果与同一用户有多个连接,则必须找到一个附加属性来隔离表示运行查询的会话的行。)

选择*

从表(dbms_xplan.display_cursor)(“我注意到使用OLEDB通过MS Access(2013)连接到Oracle 10g和11g表的区别,因为它并不总是正确识别Oracle表上的索引或主键。通过MS Access 2000数据库(使用odbc)进行相同的查询工作正常/在索引和键方面没有问题。我发现修复OLEDB版本的唯一方法是在SELECT中包含所有键字段——这不是一个令人满意的答案,但这是我能找到的全部。这可能也是尝试SSMS/OpenQuery(…)的一个选项

除此之外,您还可以尝试OPENQUERY的一些替代方案,例如:

  • 4部分名称:从服务器..Schema.Table中选择
  • 在链接服务器上执行:EXEC('select…')

但至于为什么OLEDB提供程序与本机Oracle提供程序的工作方式不同——提供程序不完全相同,本机提供程序比更通用的OLEDB提供程序更有可能克服Oracle的怪癖。

我们已经在SS端进行了跟踪-发送了正确的查询,但Oracl没有返回任何结果e、 不同的Oracle帐户,但我不明白这如何解释添加trunc“修复程序”的差异问题。结果集非常小,没有任何日期或时间戳。Openquery没有超时-用户厌倦了等待并中止。TOAD和SS在不同的机器上,具有不同的驱动程序。我们怀疑驱动程序,但我正在查找有关已知问题的特定信息。我将查看是否有类似wireshark的访问权限。我刚刚发现我们的工作场所禁止使用网络流量嗅探器
select sql_id from v$session where username = '<user running the query>';
select *
from table(dbms_xplan.display_cursor('<value from query above'));
select se.username
     , sw.event
     , sw.p1text
     , sw.p2text
     , sw.p3text
     , sw.wait_time_micro/1000000 as seconds_in_wait
     , sw.state
     , sw.time_since_last_wait_micro/1000000 as seconds_since_last_wait
  from v$session se
       inner join
       v$session_wait sw
          on se.sid = sw.sid
 where se.username = '<user running the query>'