web-dev-qa-db-fra.com

Obtenir les types de colonne de résultat de procédure stockée

J'essaie d'obtenir tout ce qu'une procédure stockée renvoie, avec les noms des colonnes et leurs types. Je peux le faire avec des tables mais je n'ai pas pu le comprendre pour les procédures stockées. J'ai essayé le sp_columns mais a seulement réussi à le faire fonctionner pour les tables.

J'ai également essayé quelque chose comme ça, mais je ne sais pas ce que je suis censé faire avec quoi.

SELECT * 
FROM SYS.PROCEDURES (NOLOCK) AS AA
INNER JOIN SYS.SCHEMAS (NOLOCK) AS BB ON (AA.schema_id = BB.schema_id)
INNER JOIN SYS.COLUMNS (NOLOCK) AS CC ON (AA.object_id = CC.object_id)

Par exemple:

USER_ID VARCHAR(200)

Je n'ai besoin que des noms des noms de colonne qu'une procédure stockée renvoie et de leurs types de données. La version de SQL Server est 2014, si cela importe.

Des idées? Merci.

8
Mein Hat

Spécifiquement pour les objets, il existe un DMV appelé sys.dm_exec_describe_first_result_set_for_object qui décrira le premier jeu de résultats si SQL Server peut déterminer ce qu'il devrait être (SQL dynamique, par exemple, ne renverra pas de résultat valide) .

Spécifiquement pour les éléments T-SQL ou liés au lot, il existe un DMV différent et une procédure stockée système accompagnée. Le DMV est sys.dm_exec_describe_first_result_set et la procédure stockée qui est parallèle au dmv est sp_describe_first_result_set .

13
Sean Gallardy

Vous devriez pouvoir utiliser la nouvelle procédure stockée système sp_describe_first_result_set pour cela - voir la documentation MSDN pour plus de détails :

EXEC sp_describe_first_result_set N'YourStoredProcedureNameHere'
11
marc_s

Si vous utilisez Openquery pour insérer les résultats de la procédure stockée dans une table temporaire, vous pouvez interroger les colonnes de la table temporaire.

Remarque, vous ne pouvez pas utiliser une @variable dans Openquery, vous devrez donc l'exécuter via SQL dynamique et un exécutable. Le problème est que la table temporaire n'existe plus en dehors de la requête dynamique. Mais, si vous placez votre table temporaire dans une requête globale, vous pouvez toujours y accéder. Ensuite, interrogez simplement les tables système pour les informations de colonne comme vous le feriez normalement.

    Create PROCEDURE TheProcedure                   
    AS                  
    BEGIN                   
        select 1 id,                
            'textstring' textstring,            
            convert(bit, 'true') boolean            

    END                 
    GO                  

    drop table ##test                   

    declare @query varchar(255)                 
    select @query =             'select * ' 
    select @query = @query +    'into ##test '              
    select @query = @query +    'from Openquery([' + @@SERVERNAME + '], ''exec misdb.dbo.TheProcedure'') '              

    EXEC(@query)                    

    select AC.name columnName,                  
        T.name dataType             
    from tempdb.Sys.columns AC                  
    join tempdb.sys.types T                 
        on AC.system_type_id = T.system_type_id             
    where object_id = object_id('tempdb.dbo.##test')
    order by AC.column_id

/*
columnName  dataType
----------  --------
id          int
textstring  varchar
boolean     bit
*/
2
solutionist