web-dev-qa-db-fra.com

Les métadonnées n'ont pas pu être déterminées car l'instruction appelle une procédure stockée étendue

dans sql server 2012, j'avais l'habitude de regarder les jobs en obtenant la sortie de 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')

Maintenant, sur le serveur SQL 2016, cela ne fonctionne pas.

Je reçois ce message d'erreur:

Msg 11520, niveau 16, état 1, procédure sp_describe_first_result_set, ligne 1 [ligne de démarrage par lots 9] Les métadonnées n'ont pas pu être déterminées car l'instruction 'EXECUTE master.dbo.xp_sqlagent_is_starting @retval OUTPUT' dans la procédure 'sp_is_sqlagent_starting' appelle une procédure stockée étendue.

lorsque vous cherchez comment obtenir les métadonnées d'une procédure stockée ,

ça dit

SET FMTONLY ON peut être utilisé pour renvoyer uniquement les informations de colonne, aucune ligne ne sera traitée ou renvoyée.

La manière qui fonctionne pour moi est celle-ci:

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

Des questions:

quel (s) changement (s) dans sql server 2016 a déclenché cela?

7
Marcello Miorelli

Rien (que je vois) n'a changé entre SQL Server 2012 et 2016 en ce qui concerne ce problème. Le fait de ne pas fonctionner avec les tables temporaires, les jeux de résultats multiples, les procédures stockées étendues, les objets CLR, etc., ont tous été des limitations de sp_describe_first_result_set Depuis son introduction dans SQL Server 2012. Donc, je pense que vous aviez réellement cela en cours d'exécution sur une version antérieure à SQL Server 2012 où cela aurait fonctionné.

Cela étant dit, même si vous avez trouvé un moyen de contourner le problème via WITH RESULT SETS, Je vous recommande vivement de jeter un œil à la définition de ces deux procédures stockées système et de copier la sous-section de code que vous utilisez réellement dans une procédure stockée qui effectue l'opération directement. De cette façon, vous n'aurez pas besoin des multiples couches d'abstraction supplémentaires que vous utilisez actuellement (par exemple OPENROWSET, etc.).

Essayez ce qui suit pour obtenir la définition. Copiez et collez le XML résultant dans l'éditeur de texte et remplacez &lt; Et &gt; Par leurs caractères respectifs < Et >:

USE [msdb];
SELECT OBJECT_DEFINITION(OBJECT_ID(N'msdb.dbo.sp_help_job')) FOR XML PATH('');
6
Solomon Rutzky