我在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