SQL Server 链接到 Oracle 的服务器在数据存在时不返回任何数据



我在SQL Server中设置了一个链接服务器来访问Oracle数据库。 我在SQL Server中有一个查询,它使用点表示法连接在Oracle表上。 我收到来自甲骨文的"找不到数据"错误。 在 Oracle 方面,我正在点击一个表(而不是视图(,并且不涉及存储过程。

首先,当没有数据时,我应该只得到零行而不是错误。
其次,在这种情况下,实际上应该有数据。
第三,我只在 PL/SQL 代码中看到 ORA-01403 错误;从不在 SQL 中。

这是完整的错误消息:
链接服务器"OM_ORACLE"的 OLE DB 提供程序"OraOLEDB.Oracle"返回消息"ORA-01403:未找到数据"。
Msg 7346,级别 16,状态 2,第 1 行无法从链接服务器"OM_ORACLE"的 OLE DB 提供程序"OraOLEDB.Oracle"获取行的数据。

这里有一些更多详细信息,但这可能没有任何意义,因为您没有我的表和数据。
这是有问题的查询:

select *
   from eopf.Batch b join eopf.BatchFile bf
                 on b.BatchID = bf.BatchID
          left outer join [OM_ORACLE]..[OM].[DOCUMENT_UPLOAD] du
                 on bf.ReferenceID = du.documentUploadID;




我不明白为什么我会收到"找不到数据"错误。 下面的查询使用相同的 Oracle 表并且不返回任何数据,但我没有得到错误 - 我只是没有返回任何行。

select * from [OM_ORACLE]..[OM].[DOCUMENT_UPLOAD] where documentUploadID = -1



下面的查询返回数据。 我刚刚从联接中删除了一个 SQL Server 表。 但是删除批处理表不会更改从 batchFile 返回的行(两种情况下都有 271 行 – batchFile 中的所有行都有一个批处理条目(。 它仍应将相同的批处理文件行联接到相同的 Oracle 行。

select *
from eopf.BatchFile bf
   left outer join [OM_ORACLE]..[OM].[DOCUMENT_UPLOAD] du
      on bf.ReferenceID = du.documentUploadID;



此查询返回 5 行。 它应该是原始查询中的相同 5。 (我不能使用它,因为我需要批处理和批处理文件表中的数据(。

       select *
   from [OM_ORACLE]..[OM].[DOCUMENT_UPLOAD] du
   where du.documentUploadId
   in
   (
   select bf.ReferenceID
   from eopf.Batch b join eopf.BatchFile bf
                 on b.BatchID = bf.BatchID);

有没有人遇到过这个错误?

今天我在内部 Join 中遇到了同样的问题。由于创建代码流失建议的表值函数或使用 user1935511 建议的临时表或更改 cymorg 建议的连接类型对我来说没有选择,因此我喜欢分享我的解决方案。

我使用连接提示将查询优化器推向正确的方向,因为问题似乎是从本地与远程表的嵌套循环连接策略引起的。对我来说,哈希合并远程连接提示有效。

对于您来说,REMOTE 将不是一个选项,因为它只能用于内部连接操作。因此,使用如下所示的内容应该有效。

select *
from eopf.Batch b
join eopf.BatchFile bf
  on b.BatchID = bf.BatchID
left outer merge join [OM_ORACLE]..[OM].[DOCUMENT_UPLOAD] du
  on bf.ReferenceID = du.documentUploadID;

我遇到了同样的问题。解决方案 1:将数据从 Oracle 数据库加载到临时表中,然后改为连接到该临时表 - 这是一个链接。

从这篇文章中,您可以发现问题可能出在使用左连接上。我已经检查了我的问题,更改查询后它解决了问题。

就我而言,我有一个由链接表制作的复杂视图,基于链接表和本地表的 3 个视图。 我自始至终都在使用内部联接,这个问题表现出来。 将联接更改为"左外联接"和"右外联接"(视情况而定(解决了该问题。

解决此问题的另一种方法是将 Oracle 数据拉回表值函数。这将导致 SQL Server 从 Oracle 检索所有数据,并将其扔到结果表变量中。 出于所有目的和目的,如果在查询中使用生成的表值函数,Oracle 数据现在是 SQL Server 的"本地"数据。

我相信最初的问题是SQL Server正在尝试优化复合查询的执行,其中包括内联的远程Oracle查询结果。 通过使用表值函数包装 Oracle 调用,SQL Server 将优化从函数返回的结果表变量的复合查询,而不是远程查询执行的结果。

CREATE function [dbo].[documents]()
returns @results TABLE (
    DOCUMENT_ID INT NOT NULL,
    TITLE VARCHAR(6) NOT NULL,
    LEGALNAME VARCHAR(50) NOT NULL,
    AUTHOR_ID INT NOT NULL,
    DOCUMENT_TYPE VARCHAR(1) NOT NULL,
    LAST_UPDATE DATETIME
) AS 
BEGIN
INSERT INTO @results
SELECT     CAST(DOCUMENT_ID AS INT) AS DOCUMENT_ID, TITLE, LEGALNAME, CAST(AUTHOR_ID AS INT) AS AUTHOR_ID, DOCUMENT_TYPE, LAST_UPDATE
FROM         OPENQUERY(ORACLE_SERVER, 
                      'select DOCUMENT_ID, TITLE, LEGALNAME, AUTHOR_ID, DOCUMENT_TYPE, FUNDTYPE, LAST_UPDATE
                       from documents')
return
END

然后,您可以使用表值函数,因为它是 SQL 查询中的表:

SELECT * FROM DOCUMENTS()

我通过避免使用=运算符来解决它。请尝试改用以下内容:

select * from [OM_ORACLE]..[OM].[DOCUMENT_UPLOAD] where documentUploadID < 0

相关内容

  • 没有找到相关文章

最新更新