5

以下查询在使用 TOAD(使用本机 Oracle 驱动程序)直接针对 Oracle 11 运行时有效

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'
) ...
;

如果从 SQL Server 2008 通过openquery(). SQL Server 有一个使用 Oracle Provider 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''
  ) ...
');

查询没有在合理的时间内返回,并且用户终止了查询。我不知道它最终是否会以正确的结果返回。

直接 TOAD 查询有效工作并且openquery()“从不”返回的版本是可重现的。

对 的小修改openquery()给出正确的有效结果:更改eff_endttrunc(eff_endt).

这很好,但似乎没有必要进行更改。

openquery()openquery()应该是通过的,那么TOAD和行为之间怎么会有区别呢?

我们关心的原因是因为我们经常使用 TOAD 直接访问 Oracle 来开发复杂的查询。一旦我们的查询功能和优化,我们将其转换为一个openquery()字符串,以便在 SQL Server 应用程序中使用。openquery()当我们知道它作为直接查询工作时,查询突然失败是非常严重的。然后我们必须通过反复试验寻找解决方法。

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

有谁知道任何驱动程序,或蟾蜍,或???可能导致差异的问题?有没有办法消除这个问题,使两种方法总是给出相同的结果?

4

3 回答 3

1

以下是您可以检查的基本内容,以查看数据库在收到查询后正在执行的操作。首先,检查 TOAD 中的执行计划是否与使用 openquery 运行查询时相同。您可以使用以下方法在 TOAD 中自己计划查询:

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

select *
from table(dbms_xplan.display(statement_id => 'openquery_test';

然后让某人使用 openquery() 启动查询,并让某人有权查看 v$ 表以运行:

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>'

;

(同样,如果有多个会话使用相同的用户名,您将需要另一个属性将其缩减为您感兴趣的会话。)

如果计划不同,那么您需要找出原因,或者如果它们相同,请查看它在等待什么(例如 SQL*Net 向客户端发送消息?)以及原因。

于 2013-08-09T20:17:30.370 回答
1

我知道你前一阵子问过这个问题,但我刚刚遇到了你的问题。

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

我一边打字一边大声思考……

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

应该返回多少行?

如果在 oracle 选择中限制返回的行怎么办?

openquery 超时有多快?

TOAD和SS在同一台机器上吗?您是否正在 RDP 进入 SS 并从那里运行 toad?

他们使用相同的驱动程序吗?包括位?(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 看看toad 和ss 实际发送了什么。

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

于 2013-08-06T06:29:43.357 回答
0

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

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

  • 4 部分名称:SELECT ... FROM Server..Schema.Table
  • 在链接服务器上执行 AT: EXEC ('select...')

但至于为什么 OLEDB 提供程序与原生 Oracle 提供程序的工作方式不同 - 提供程序并不相同,而且原生提供程序比更通用的 OLEDB 提供程序更有可能掩盖 Oracle 的怪癖。

于 2013-08-09T21:12:24.663 回答