简体   繁体   English

T-SQL:无法从链接服务器的OLE DB提供程序“ OraOLEDB.Oracle”中获取行的数据

[英]T-SQL: cannot get the data of the row from the OLE DB provider “OraOLEDB.Oracle” for linked server

Error is: 错误是:

Cannot get the data of the row from the OLE DB provider "OraOLEDB.Oracle" for linked server 无法从链接服务器的OLE DB提供程序“ OraOLEDB.Oracle”获取行的数据

I'm trying to convert an Oracle SQL query to T-SQL. 我正在尝试将Oracle SQL查询转换为T-SQL。 I get the error when I run this version of the query: 运行此版本的查询时出现错误:

SELECT B.SAAS_ACTIVITY, A.LAST_NAME, A.FIRST_NAME, A.MIDDLE_NAME,  
        B.DIVISION_CODE, B.GRANT_YEAR, B.ACTIVITY_CODE, B.ACT_ACTIVITY_CODE,
        B.COST_CENTER, B.HOURS_BEG, B.LEAVE_ADJ_HOURS, B.CURRENT_MONTH,
        B.HOURS_BEG + B.LEAVE_ADJ_HOURS TOTAL_HOURS, B.PERCENT_WORK, 
        B.DIV_MONTHLY_SALARY, C.DIV_DESCRIPTION,
        B.DIV_SALARY_PLUS_FRINGE - B.DIV_MONTHLY_SALARY FRINGE, 
        B.DIV_SALARY_PLUS_FRINGE
  FROM ORCL_RIVENDELL..BP2K.EMT_EMPLOYEE A, 
ORCL_RIVENDELL..BP2K.LABOR_DISTRIB_MASTER_DETAIL B, 
    ORCL_RIVENDELL..BP2K.ACT_DIVISION C
  WHERE A.ID = B.ID
       AND B.FISCAL_YEAR = :P_SFY
       AND B.DIVISION_CODE = C.DIVISION_CODE
       AND C.DIV_SFY = :P_SFY
       AND B.CURRENT_MONTH >= CASE WHEN :P_FROM_MONTH is null THEN 2 
            ELSE :P_FROM_MONTH
            END
       AND B.CURRENT_MONTH <= CASE WHEN :P_TO_MONTH is null THEN 13 
           ELSE :P_TO_MONTH
           END
       AND B.SAAS_ACTIVITY >= CASE WHEN :P__FROM_OFFICE  is null THEN '4701' 
           ELSE :P_FROM_OFFICE
           END
       AND B.SAAS_ACTIVITY <= CASE WHEN :P__TO_OFFICE  is null THEN '4705' 
           ELSE :P_TO_OFFICE
           END
       AND B.DIVISION_CODE >= CASE WHEN :P__FROM_DIV  is null THEN '0011' 
           ELSE :P_FROM_DIV
           END
      AND B.DIVISION_CODE <= CASE WHEN :P__TO_DIV  is null THEN '9999' 
           ELSE :P_TO_DIV
           END
      AND B.DIVISION_CODE <> '1050'
ORDER BY B.DIVISION_CODE, A.LAST_NAME, B.CURRENT_MONTH

But if remove the join to get the DIV_DESCRIPTION, and just go with the DIV_CODE, the query runs fine: 但是,如果删除联接以获取DIV_DESCRIPTION,而仅使用DIV_CODE,则查询运行良好:

SELECT B.SAAS_ACTIVITY, A.LAST_NAME, A.FIRST_NAME, A.MIDDLE_NAME,  
        B.DIVISION_CODE, B.GRANT_YEAR, B.ACTIVITY_CODE, B.ACT_ACTIVITY_CODE,
        B.COST_CENTER, B.HOURS_BEG, B.LEAVE_ADJ_HOURS, B.CURRENT_MONTH,
        B.HOURS_BEG + B.LEAVE_ADJ_HOURS TOTAL_HOURS, B.PERCENT_WORK, 
        B.DIV_MONTHLY_SALARY, B.DIVISION_CODE,
        B.DIV_SALARY_PLUS_FRINGE - B.DIV_MONTHLY_SALARY FRINGE, 
        B.DIV_SALARY_PLUS_FRINGE
  FROM ORCL_RIVENDELL..BP2K.EMT_EMPLOYEE A, 
     ORCL_RIVENDELL..BP2K.LABOR_DISTRIB_MASTER_DETAIL B
  WHERE A.ID = B.ID
       AND B.FISCAL_YEAR = :P_SFY
       AND B.CURRENT_MONTH >= CASE WHEN :P_FROM_MONTH is null THEN 2 
            ELSE :P_FROM_MONTH
            END
       AND B.CURRENT_MONTH <= CASE WHEN :P_TO_MONTH is null THEN 13 
           ELSE :P_TO_MONTH
           END
       AND B.SAAS_ACTIVITY >= CASE WHEN :P__FROM_OFFICE  is null THEN '4701' 
           ELSE :P_FROM_OFFICE
           END
       AND B.SAAS_ACTIVITY <= CASE WHEN :P__TO_OFFICE  is null THEN '4705' 
           ELSE :P_TO_OFFICE
           END
       AND B.DIVISION_CODE >= CASE WHEN :P__FROM_DIV  is null THEN '0011' 
           ELSE :P_FROM_DIV
           END
      AND B.DIVISION_CODE <= CASE WHEN :P__TO_DIV  is null THEN '9999' 
           ELSE :P_TO_DIV
           END
      AND B.DIVISION_CODE <> '1050'
ORDER BY B.DIVISION_CODE, A.LAST_NAME, B.CURRENT_MONTH

Getting the DIV_DESCRIPTION is not absolutely critical, but I would like to understand why the error is occurring (I've worked with Oracle SQL much more than TSQL). 获取DIV_DESCRIPTION并不是绝对关键,但是我想了解为什么会发生错误(与TSQL相比,我使用Oracle SQL的工作更多)。 The column is defined as VARCHAR2(12) in both the ACT_DIVISION table and the LABOR_DISTRIB_MASTER_DETAIL table. 该列在ACT_DIVISION表和LABOR_DISTRIB_MASTER_DETAIL表中均定义为VARCHAR2(12)。 IS this a data type mismatch thing, or something else? 这是数据类型不匹配的东西,还是其他?

Thanks, Harry 谢谢,哈利

I recommend letting Oracle do all the grunt work for you by passing the query over via an OPENQUERY , its much easier on you (since you know Oracle syntax) and faster, since Oracle will do its own work on its own tables with its own indexes and only pass back the resultset to SQL Server. 我建议让Oracle通过OPENQUERY传递查询来为您完成所有繁琐的工作,因为您将使用自己的索引在自己的表上进行自己的工作,这使您的工作更加轻松(因为您知道Oracle语法)并且仅将结果集传递回SQL Server。

Note since the query is contained in ' ' you have to double up the single ' within it. 注意,由于查询包含在' '您必须将其中的单个'加倍'

In doing this, the OLEDB driver should handle all the wonky datatype mapping for you. 为此,OLEDB驱动程序应为您处理所有不可靠的数据类型映射。

Syntax: 句法:

SELECT *
FROM OPENQUERY([ORCL_RIVENDELL],'SELECT B.SAAS_ACTIVITY, A.LAST_NAME, A.FIRST_NAME, A.MIDDLE_NAME,  
        B.DIVISION_CODE, B.GRANT_YEAR, B.ACTIVITY_CODE, B.ACT_ACTIVITY_CODE,
        B.COST_CENTER, B.HOURS_BEG, B.LEAVE_ADJ_HOURS, B.CURRENT_MONTH,
        B.HOURS_BEG + B.LEAVE_ADJ_HOURS TOTAL_HOURS, B.PERCENT_WORK, 
        B.DIV_MONTHLY_SALARY, C.DIV_DESCRIPTION,
        B.DIV_SALARY_PLUS_FRINGE - B.DIV_MONTHLY_SALARY FRINGE, 
        B.DIV_SALARY_PLUS_FRINGE
  FROM BP2K.EMT_EMPLOYEE A, 
       BP2K.LABOR_DISTRIB_MASTER_DETAIL B, 
       BP2K.ACT_DIVISION C
  WHERE A.ID = B.ID
       AND B.FISCAL_YEAR = :P_SFY
       AND B.DIVISION_CODE = C.DIVISION_CODE
       AND C.DIV_SFY = :P_SFY
       AND B.CURRENT_MONTH >= CASE WHEN :P_FROM_MONTH is null THEN 2 
            ELSE :P_FROM_MONTH
            END
       AND B.CURRENT_MONTH <= CASE WHEN :P_TO_MONTH is null THEN 13 
           ELSE :P_TO_MONTH
           END
       AND B.SAAS_ACTIVITY >= CASE WHEN :P__FROM_OFFICE  is null THEN ''4701'' 
           ELSE :P_FROM_OFFICE
           END
       AND B.SAAS_ACTIVITY <= CASE WHEN :P__TO_OFFICE  is null THEN ''4705'' 
           ELSE :P_TO_OFFICE
           END
       AND B.DIVISION_CODE >= CASE WHEN :P__FROM_DIV  is null THEN ''0011'' 
           ELSE :P_FROM_DIV
           END
      AND B.DIVISION_CODE <= CASE WHEN :P__TO_DIV  is null THEN ''9999'' 
           ELSE :P_TO_DIV
           END
      AND B.DIVISION_CODE <> ''1050''
ORDER BY B.DIVISION_CODE, A.LAST_NAME, B.CURRENT_MONTH')

If you need to pass parameters, here is the syntax: 如果您需要传递参数,则语法如下:

Let's assume you have a parameter called @myDate you need to pass. 假设您需要传递一个名为@myDate的参数。

DECLARE @myDate DATETIME=GETDATE()

DECLARE @SQL NVARCHAR(MAX)

SET @SQL = 'SELECT *
            FROM OPENQUERY([ORCL_RIVENDELL],''SELECT *
                                                FROM  BP2K.SOME_TABLE
                                                WHERE ACTIVITYDATE = '''''+CONVERT(VARCHAR,@myDate,120)+''''' '')'

PRINT @SQL
--EXEC SP_EXECUTESQL @SQL

All that said, you need to be VERY VERY careful using dynamic SQL, its dangerous if you do not control the input to these parameters. 综上所述,使用动态SQL时要非常小心,如果不控制这些参数的输入,这很危险。 You open yourself to SQL Injection attacks this way. 您可以通过这种方式对SQL注入攻击开放。 There are better/safer ways to pass parameters into sp_executesql but it would not work when using an OPENQUERY . 有更好/更安全的方法可以将参数传递到sp_executesql但是在使用OPENQUERY时不起作用。 If you can validate the input using ISDATE() or ISNUMERIC() all the better, don't execute if they don't pass validation. 如果可以使用ISDATE()ISNUMERIC()更好地验证输入,则如果它们未通过验证,请不要执行。 But your safest bet is to NEVER allow anyone but you to pass these parameters in, ever. 但是,最安全的选择是永远禁止除您之外的任何人传入这些参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 执行proc时:无法从OLE DB提供程序“ OraOLEDB.Oracle”获取链接服务器的行 - When Executing proc: Cannot fetch a row from OLE DB provider “OraOLEDB.Oracle” for linked server 创建从 SQL Server 到 Oracle 的链接服务器时,无法创建 OLE DB 提供程序“OraOLEDB.Oracle”错误的实例 - Cannot create an instance of OLE DB Provider 'OraOLEDB.Oracle' error when creating linked servers from SQL Server to Oracle 无法初始化链接服务器的 OLE DB 提供程序“OraOLEDB.Oracle”的数据源对象 - Cannot initialize the data source object of OLE DB provider "OraOLEDB.Oracle" for linked server 如何修复错误“灾难性故障。无法从链接服务器的 OLE DB 提供程序“OraOLEDB.Oracle”获取行” - How to fix error "Catastrophic failure. Cannot fetch a row from OLE DB provider "OraOLEDB.Oracle" for linked server" 链接服务器的OLE DB提供程序“ OraOLEDB.Oracle”返回消息“ ROW-00004:无效的列数据类型” - OLE DB provider “OraOLEDB.Oracle” for linked server returned message “ROW-00004: Invalid column datatype” 链接服务器[ORA]的OLE DB提供程序[OraOLEDB.Oracle]返回了消息ORA-00936:缺少表达式 - OLE DB provider [OraOLEDB.Oracle] for linked server [ORA] returned message ORA-00936: missing expression 链接服务器的OLE DB提供程序“ OraOLEDB.Oracle”返回消息“ ORA-06576:无效的函数或过程名称” - OLE DB provider “OraOLEDB.Oracle” for linked server returned message “ORA-06576: not a valid function or procedure name” 在链接服务器提供程序中找不到OraOLEDB.Oracle提供程序 - Unable to find OraOLEDB.Oracle provider in the Linked Server Providers 如何通过批量插入导入SQL Server? 无法从OLE DB提供程序“ BULK”获取链接服务器“(空)”的行 - How to import with bulk insert into SQL Server? Cannot fetch a row from OLE DB provider “BULK” for linked server “(null)” SQL-Server 中的 CLR 编程问题(System.InvalidOperationException: The 'OraOLEDB.Oracle' provider is not registered on local machine) - CLR programming in SQL-Server problem(System.InvalidOperationException: The 'OraOLEDB.Oracle' provider is not registered on the local machine)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM