8

我在 SQL Server 中有一个链接服务器设置来访问 Oracle 数据库。我在 SQL Server 中有一个使用点表示法连接 Oracle 表的查询。我从 Oracle 收到“未找到数据”错误。在 Oracle 方面,我正在访问一个表(不是视图)并且不涉及存储过程。

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

这是完整的错误消息:
链接服务器“OM_ORACLE”的 OLE DB 提供程序“OraOLEDB.Oracle”返回消息“ORA-01403:未找到数据”。
消息 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 表。但是删除批处理表不会更改从批处理文件返回的行(两种情况下都是 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);

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

4

5 回答 5

3

今天我在内部加入时遇到了同样的问题。由于创建 codechurn 建议的表值函数或使用user1935511建议的临时表或更改cymorg建议的连接类型对我来说没有选择,我想分享我的解决方案。

我使用Join Hints将查询优化器推向正确的方向,因为问题似乎是由本地远程表的嵌套循环连接策略引起的。对我来说HASHMERGEREMOTE加入提示有效。

对于您来说,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;
于 2016-11-16T09:03:12.673 回答
1

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

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

于 2013-10-10T08:02:40.500 回答
0

就我而言,我有一个由链接表组成的复杂视图,3 个基于链接表的视图和一个本地表。我一直在使用内连接,这个问题就显现出来了。将连接更改为左外连接和右外连接(视情况而定)解决了该问题。

于 2015-04-09T11:40:26.047 回答
0

我通过避开=操作员解决了这个问题。尝试改用这个:

select * from [OM_ORACLE]..[OM].[DOCUMENT_UPLOAD] where documentUploadID < 0
于 2016-03-22T19:26:50.490 回答
0

解决此问题的另一种方法是将 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()

于 2016-04-28T15:50:04.123 回答