无法确定元数据,因为语句调用了扩展存储过程

Mar*_*lli 9 sql-server dynamic-sql jobs openrowset sql-server-2016

在 sql server 2012 中,我曾经通过获取 SP_HELP_JOB 的输出来查看作业

-- https://www.sqlservercentral.com/Forums/Topic259078-8-1.aspx
-- getting data from sp_help_job into a temp table
-- marcelo miorelli
-- 01-april-2013

IF OBJECT_ID('TEMPDB..#JOBiNFO') IS NOT NULL
   DROP TABLE #JobInfo

IF OBJECT_ID('TEMPDB..#ScheduleInfo') IS NOT NULL
   DROP TABLE #ScheduleInfo


SELECT * INTO #JobInfo
FROM OPENROWSET('sqloledb', 'server=(local);trusted_connection=yes'
, 'set fmtonly off exec msdb.dbo.sp_help_job -- @execution_status=4')


SELECT * INTO #ScheduleInfo
FROM OPENROWSET('sqloledb', 'server=(local);trusted_connection=yes'
, 'set fmtonly off  exec msdb.dbo.sp_help_schedule')
Run Code Online (Sandbox Code Playgroud)

现在在 sql server 2016 上这不起作用。

我收到此错误消息:

消息 11520,级别 16,状态 1,过程 sp_describe_first_result_set,第 1 行 [批处理开始行 9] 无法确定元数据,因为过程“sp_is_sqlagent_starting”中的语句“EXECUTE master.dbo.xp_sqlagent_is_starting @retval OUTPUT”调用了扩展存储过程。

在寻找如何获取存储过程的元数据时

它说

SET FMTONLY ON 可用于仅返回列信息,不会处理或返回任何行。

对我有用的方法是这样的:

IF OBJECT_ID('TEMPDB..#JOBiNFO') IS NOT NULL
   DROP TABLE #JobInfo


SELECT * INTO #JobInfo
FROM OPENROWSET('sqloledb', 'server=(local);trusted_connection=yes'
, 'set fmtonly off;

DECLARE 
  @job_id                     UNIQUEIDENTIFIER = NULL,  
  @job_name                   SYSNAME          = NULL,  
  @job_aspect                 VARCHAR(9)       = NULL,  
  @job_type                   VARCHAR(12)      = NULL,
  @owner_login_name           SYSNAME          = NULL,
  @subsystem                  NVARCHAR(40)     = NULL,
  @category_name              SYSNAME          = NULL,
  @enabled                    TINYINT          = NULL,
  @execution_status           INT              = NULL,
  @date_comparator            CHAR(1)          = NULL,
  @date_created               DATETIME         = NULL,
  @date_last_modified         DATETIME         = NULL,
  @description                NVARCHAR(512)    = NULL

        EXEC msdb.dbo.sp_help_job @job_id,  
            @job_name,
            @job_aspect,
            @job_type,
            @owner_login_name,
            @subsystem,
            @category_name,
            @enabled,
            @execution_status,
            @date_comparator,
            @date_created,
            @date_last_modified,
            @description
            WITH RESULT SETS
            ( 
             (
                job_id                      UNIQUEIDENTIFIER, 
                originating_server          NVARCHAR(30), 
                name                        SYSNAME, 
                [enabled]                   TINYINT, 
                [description]               NVARCHAR(512), 
                start_step_id               INT, 
                category                    SYSNAME, 
                [owner]                     SYSNAME, 
                notify_level_eventlog       INT, 
                notify_level_email          INT, 
                notify_level_netsend        INT, 
                notify_level_page           INT, 
                notify_email_operator       SYSNAME, 
                notify_netsend_operator     SYSNAME, 
                notify_page_operator        SYSNAME, 
                delete_level                INT, 
                date_created                DATETIME, 
                date_modified               DATETIME, 
                version_number              INT, 
                last_run_date               INT, 
                last_run_time               INT, 
                last_run_outcome            INT, 
                next_run_date               INT, 
                next_run_time               INT, 
                next_run_schedule_id        INT, 
                current_execution_status    INT, 
                current_execution_step      SYSNAME, 
                current_retry_attempt       INT, 
                has_step                    INT, 
                has_schedule                INT, 
                has_target                  INT, 
                [type]                      INT 
             )
             )
')
Run Code Online (Sandbox Code Playgroud)

问题:

触发此问题的 sql server 2016 中的更改是什么?

Sol*_*zky 6

关于这个问题,SQL Server 2012 和 2016 之间没有任何变化(我可以看到)。不使用临时表、多个结果集、扩展存储过程、CLR 对象等都是sp_describe_first_result_setSQL Server 2012 中引入的限制。所以,我认为你实际上在 SQL Server 之前的版本上运行了它2012 年它会起作用。

话虽如此,虽然您确实找到了解决方法 via WITH RESULT SETS,但我仍然强烈建议您查看这两个系统存储过程的定义,并将您实际使用的代码小节复制到执行以下操作的存储过程中直接操作。这样您就不需要当前使用的多个额外抽象层(例如OPENROWSET,等)。

尝试以下操作以获取定义。将生成的 XML 复制并粘贴到文本编辑器中,&lt;&gt;用它们各自的<>字符替换和:

USE [msdb];
SELECT OBJECT_DEFINITION(OBJECT_ID(N'msdb.dbo.sp_help_job')) FOR XML PATH('');
Run Code Online (Sandbox Code Playgroud)

  • +1 很高兴见到你 `OBJECT_DEFINITION`,谢谢 srutzky (2认同)