【问题标题】:Execute stored proc with OPENQUERY使用 OPENQUERY 执行存储过程
【发布时间】:2011-05-08 18:01:19
【问题描述】:

我有带有链接 Sybase 服务器的 SQL Server 2008,我正在尝试使用 OPENQUERY 在 Sybase 服务器上执行存储过程。如果我有一个不带参数的存储过程,它会成功。如果我有一个带有参数的存储过程,它会失败。我什至尝试了一个非常基本的存储过程,它只接受了一个仍然失败的 int。以下是我使用的语法:

select * from 
OPENQUERY([LINKSERVER],'exec database.user.my_stored_proc ''AT'',''XXXX%'',''1111'',1')

消息 7357,第 16 级,状态 2,第 3 行 无法处理对象“exec database.user.my_stored_proc 'AT','XXXX%','1111',1”。链接服务器“LINKSERVER”的 OLE DB 提供程序“ASEOLEDB”表明该对象没有列或当前用户对该对象没有权限。

由于 proc 在没有参数的情况下可以正常执行,我认为这不是权限问题。

【问题讨论】:

  • 您是否尝试直接在 Sybase 上运行 SQL 文本?
  • 是的,在 Sybase 上执行得很好

标签: sql sql-server tsql sybase openquery


【解决方案1】:

Linked Servers 和 OPENQUERY,Gems 到 MS SQL Server...这些都是披着羊皮的狼。在处理参数时,我发现了以下解决方案

  1. 如果 SP 基本上只是 SELECT 语句,则将其移至 VIEW 并通过 OPENQUERY 传递 SQL 语句。

  2. 将 OPENQUERY 构建为字符串,然后使用 execute_sql。

【讨论】:

    【解决方案2】:

    您还可以查看是否可以在 exec 之前使用 SET FMTONLY ON:

    OPENQUERY([LINKSERVER],'SET FMTONLY ON; exec database.user.my_stored_proc ''AT'',''XXXX%'',''1111'',1')

    如果你尝试这个并且它有效,你可能应该谷歌 FMTONLY+OPENQUERY 来了解它的含义。

    【讨论】:

      【解决方案3】:

      这对我有用,

      SELECT * FROM OPENQUERY(LOCALSERVER, 'SET FMTONLY OFF EXEC snr.dbo.GetAllSignals @controlRunId = 25, @experimentRunId = 26')
      

      我正在创建临时表,这就是我被拒绝访问的原因

      这里有更多信息http://www.sommarskog.se/share_data.html#OPENQUERY

      【讨论】:

      • +1 这对我也有用。谢谢!我没有使用临时表,但我在远程 proc 中执行 EXEC(@VariableWithQuery),该变量是从 SELECT 语句中设置的。在我添加“SET FMTONLY OFF”之前,这不起作用;到开始。但是,如果我通过 SET 命令设置变量,那么它确实可以在不需要 SET FMTONLY 的情况下工作。奇数。
      • 公平警告,此方法可能会产生一些意想不到的后果,如本答案所述:stackoverflow.com/a/14299989;但是,这是“让它工作”并避免处理 DTC 的最简单方法,这可能更糟糕,所以这个 (SET FMTONLY OFF) 是一个公平的解决方法。
      • 这引导我朝着正确的方向前进,但这并不是 100% 正确的。对我来说,解决问题的方法是更改​​我的存储过程以包含“设置 NOCOUNT ON”
      • "Set NOCOUNT ON" 必须在存储过程中设置,以使 SET FMTONLY=OFF 生效。我实际上在存储过程中添加了所有这些。 --DBCC 用户选项设置 ARITHABORT 开启;设置 ANSI_NULL_DFLT_ON 开;设置 CONCAT_NULL_YIELDS_NULL 开;设置 ANSI_NULLS 开;设置 ANSI_WARNINGS 开;设置无计数;
      【解决方案4】:

      我创建了一个不返回任何值且不起作用的 sp。 您在 mysql 中的 SP 必须返回一个值! 例如我在“mysql”中这样做:

      CREATE DEFINER=`root`@`localhost` PROCEDURE `MyPro`(IN `Name` VARCHAR(50), IN `Id` INT, OUT `Result` INT)
      MODIFIES SQL DATA
      BEGIN
      DECLARE Result INT;
          SET Result = 0;
      INSERT into MyTable (Id,Name)  VALUES(Id,Name);
      SELECT Result;
      
      END
      

      “Id”和“Name”为输入参数,“Result”为输出参数 并在 SQL SERVER 中创建链接服务器并像这样调用它:

      select * from openquery
      (
          Test,'call mydb.MyPro(''Name'',''16'', @P0);'
      )
      

      它对我有用:D

      【讨论】:

        【解决方案5】:

        试试这个,

        SELECT * FROM OPENQUERY(linked_server_name, 'SELECT postgres_procedure_name (parameters)');

        【讨论】:

          【解决方案6】:

          我遇到了一个非常相似的问题,但我的 SP 没有采用任何参数。 我尝试更改通过 openquery 发送的查询以包含“SET NOCOUNT ON”和“SET FMTONLY OFF”,但这没有区别。

          对我的存储过程有效的唯一解决方案是删除现有版本,并将代码更改为专门的“SET NOCOUNT ON”

          完成此操作后,我能够通过我的链接服务器连接成功运行我的存储过程。

          【讨论】:

            【解决方案7】:

            首先你必须添加硬编码文本字段然后你必须 用您的参数值替换它,例如 FromDate,TillDate,EmpID,CompCode,0,DeptID,DesgId,LocationID,AtnType


            DECLARE @startdate varchar(255) =   '2019-12-17'
            DECLARE @enddate     varchar(255)    =  '2019-12-17'
            
            Set  @SQL = 'SELECT  *  FROM OPENQUERY(' + quotename(@LinkedServer) + ',' + '''' +
             'SET FMTONLY OFF; exec [TAP].[dbo].[GetAttendanceList] '  + 'FromDate,TillDate,EmpID,CompCode,0,DeptID,DesgId,LocationID,AtnType,1'')'
            

            您必须替换下面显示的参数值

            set @SQL=REPLACE(@SQL,'FromDate',+''''+''''+@startdate+''''+'''')
            
              set @SQL=REPLACE(@SQL,'TillDate',+''''+''''+@enddate+''''+'''')
            
              set @SQL=REPLACE(@SQL,'CompCode',+''''+''''+@CompCode+''''+'''')
            
                set @SQL=REPLACE(@SQL,'AtnType',+''''+''''+''''+'''')
            
             if @EmpID is Null
              begin
               set @SQL=REPLACE(@SQL,'EmpID','null')
              end
            
              if @DeptID is Null
              begin
               set @SQL=REPLACE(@SQL,'DeptID','null')
              end
            
                if @DesgId is Null
              begin
               set @SQL=REPLACE(@SQL,'DesgId','null')
              end
            
               if @LocationID is Null
              begin
               set @SQL=REPLACE(@SQL,'LocationID','null')
              end
            
            
              print @SQL
              exec ( @SQL)
            

            【讨论】:

            • 嗨阿里侯赛因,欢迎。请考虑改进格式,很难阅读。
            猜你喜欢
            • 2015-09-21
            • 1970-01-01
            • 1970-01-01
            • 2014-06-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多