sql server linked server to oracle returns no data found when data exists

感情迁移 提交于 2019-12-18 08:10:06

问题


I have a linked server setup in SQL Server to hit an Oracle database. I have a query in SQL Server that joins on the Oracle table using dot notation. I am getting a “No Data Found” error from Oracle. On the Oracle side, I am hitting a table (not a view) and no stored procedure is involved.

First, when there is no data I should just get zero rows and not an error.
Second, there should actually be data in this case.
Third, I have only seen the ORA-01403 error in PL/SQL code; never in SQL.

This is the full error message:
OLE DB provider "OraOLEDB.Oracle" for linked server "OM_ORACLE" returned message "ORA-01403: no data found".
Msg 7346, Level 16, State 2, Line 1 Cannot get the data of the row from the OLE DB provider "OraOLEDB.Oracle" for linked server "OM_ORACLE".

Here are some more details, but it probably does not mean anything since you don’t have my tables and data.
This is the query with the problem:

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;




I can’t understand why I get a “no data found” error. The query below uses the same Oracle table and returns no data but I don’t get an error - I just get no rows returned.

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



The query below returns data. I just removed one of the SQL Server tables from the join. But removing the batch table does not change the rows returned from batchFile (271 rows in both cases – all rows in batchFile have a batch entry). It should still be joining the same batchFile rows to the same Oracle rows.

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



And this query returns 5 rows. It should be the same 5 from the original query. ( I can’t use this because I need data from the batch and batchFile table).

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

Has anyone experienced this error?


回答1:


Today I experienced the same problem with an inner Join. As creating a Table Valued Function suggested by codechurn or using a Temporary Table suggested by user1935511 or changing the Join Types suggested by cymorg are no options for me, I like to share my solution.

I used Join Hints to drive the query optimizer into the right direction, as the problem seems to rise up from nested loops join strategy with the remote table locally . For me HASH, MERGE and REMOTE join hints worked.

For you REMOTE will not be an option because it can be used only for inner join operations. So using something like the following should work.

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;



回答2:


I've had the same problem. Solution1: load the data from the Oracle database into a temp table, then join to that temp table instead - here's a link.

From this post a link you can find out that the problem can be with using left join. I've checked with my problem and after changing my query it solved the problem.




回答3:


In my case I had a complex view made from a linked table, 3 views based on the linked table and a local table. I was using Inner Joins throughout and this problem manifested. Changing the joins to Left and Right Outer Joins (as appropriate) resolved the issue.




回答4:


I got the same problem and resolved it by avoiding the '=' operator try using

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

Instead.

Thanks




回答5:


Another way to work around the problem is to pull back the Oracle data into a Table Valued Function. This will cause SQL Server to go out and retrieve all of the data from Oracle and throw it into a resultant table variable. For all intent and purpose, the Oracle data is now "local" to SQL Server if you use the resultant Table Valued Function in a query.

I believe the original problem is that SQL Server is trying to optimize the execution of your compound query which includes the remote Oracle query results in-line. By using a Table Valued Function to wrap the Oracle call, SQL Server will optimize the compound query on the resultant table variable returned from the function and not the results from the remote query execution.

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

You can then use the Table Valued Function as it it were a table in your SQL queries:

SELECT * FROM DOCUMENTS()



来源:https://stackoverflow.com/questions/19225551/sql-server-linked-server-to-oracle-returns-no-data-found-when-data-exists

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!