Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment redéfinir les colonnes renvoyées par une procédure stockée dans SQL Server

Lorsque vous exécutez une procédure stockée qui renvoie un jeu de résultats dans SQL Server, les colonnes renvoyées sont définies dans la procédure stockée.

Mais saviez-vous que vous pouvez redéfinir ces colonnes ?

Ce que je veux dire, c'est que vous pouvez modifier les noms et/ou le type de données des colonnes renvoyées dans le jeu de résultats.

Cela pourrait vous éviter d'avoir à manipuler les en-têtes de colonne et les formats de données au cas où vous auriez besoin d'utiliser cet ensemble de résultats dans un autre paramètre.

Par exemple, si une procédure stockée renvoie une datetime2 colonne, mais vous n'avez besoin que de la partie date, vous pouvez spécifier date pour cette colonne, et votre ensemble de résultats n'inclura que la partie date.

Et la meilleure partie est que vous pouvez le faire dans le cadre de l'EXECUTE déclaration. Pas besoin de masser les données après avoir exécuté la procédure. Pour ce faire, utilisez le WITH RESULT SETS clause de EXECUTE déclaration.

Exemple

Voici un exemple pour montrer comment utiliser le WITH RESULT SETS clause pour modifier les noms de colonne et les types de données à partir du jeu de résultats d'une procédure stockée.

Résultats bruts

Examinons d'abord les résultats bruts d'une procédure stockée.

EXEC sp_getCityById @CityId = 1;

Résultat :

+------------+----------------------------+-----------------------------+
| CityName   | LatestRecordedPopulation   | ValidFrom                   |
|------------+----------------------------+-----------------------------|
| Aaronsburg | 613                        | 2013-01-01 00:00:00.0000000 |
+------------+----------------------------+-----------------------------+

Selon nos besoins, nous pourrions souhaiter que la procédure n'utilise pas un en-tête de colonne aussi long pour la population (LatestRecordedPopulation ).

Nous pourrions également souhaiter que le ValidFrom la colonne n'incluait pas la partie horaire, car elle occupe un espace inutile et n'est pas importante pour notre objectif particulier.

Nous pourrions également souhaiter présenter les en-têtes de colonne avec un espace, juste pour le rendre un peu plus présentable pour la personne à qui nous l'enverrons.

Redéfinir les colonnes

Maintenant, allons-y et utilisons le WITH RESULT SETS clause pour redéfinir les colonnes.

EXEC sp_getCityById @CityId = 1
WITH RESULT SETS   
(  
    (
        [City] nvarchar(50),
        [Population] int,
        [Valid From] date
    )
);

Résultat :

+------------+--------------+--------------+
| City       | Population   | Valid From   |
|------------+--------------+--------------|
| Aaronsburg | 613          | 2013-01-01   |
+------------+--------------+--------------+

Donc, en utilisant le WITH RESULT SETS clause, nous avons pu modifier les noms de colonne et le type de données.

En fait, dans cet exemple, j'ai changé le type de données des deux dernières colonnes de bigint en entier , et de datetime2(7) à à ce jour , respectivement.

Analyser les ensembles de résultats

Nous pouvons utiliser des vues de gestion dynamiques telles que sys.dm_exec_describe_first_result_set et sys.dm_exec_describe_first_result_set_for_object pour connaître les types de données réels de chaque ensemble de résultats.

Voici un exemple d'utilisation de sys.dm_exec_describe_first_result_set_for_object pour obtenir les noms de colonnes et leurs types de données respectifs renvoyés par la procédure stockée.

SELECT 
    name,
    system_type_name,
    max_length,
    [precision],
    scale,
    user_type_name
FROM sys.dm_exec_describe_first_result_set_for_object(OBJECT_ID('sp_getCityById'), 0);

Résultat :

+--------------------------+--------------------+--------------+-------------+---------+------------------+
| name                     | system_type_name   | max_length   | precision   | scale   | user_type_name   |
|--------------------------+--------------------+--------------+-------------+---------+------------------|
| CityName                 | nvarchar(50)       | 100          | 0           | 0       | NULL             |
| LatestRecordedPopulation | bigint             | 8            | 19          | 0       | NULL             |
| ValidFrom                | datetime2(7)       | 8            | 27          | 7       | NULL             |
+--------------------------+--------------------+--------------+-------------+---------+------------------+

Ce sont donc les noms de colonne et les types de données réels renvoyés dans le jeu de résultats (sans rien redéfinir).

Nous pouvons voir que les deux dernières colonnes sont bigint et datetime2(7) respectivement.

Utilisons maintenant sys.dm_exec_describe_first_result_set pour obtenir les métadonnées de notre requête modifiée.

SELECT 
    name,
    system_type_name,
    max_length,
    [precision],
    scale,
    user_type_name
FROM sys.dm_exec_describe_first_result_set(
    'EXEC sp_getCityById @CityId = 1
        WITH RESULT SETS   
        (  
            (
                [City] nvarchar(50),
                [Population] int,
                [Valid To] date
            )
        );', 
        null, 
        0
    );

Résultat :

+------------+--------------------+--------------+-------------+---------+------------------+
| name       | system_type_name   | max_length   | precision   | scale   | user_type_name   |
|------------+--------------------+--------------+-------------+---------+------------------|
| City       | nvarchar(50)       | 100          | 0           | 0       | NULL             |
| Population | int                | 4            | 10          | 0       | NULL             |
| Valid To   | date               | 3            | 10          | 0       | NULL             |
+------------+--------------------+--------------+-------------+---------+------------------+

Nous pouvons donc voir que les noms de colonne ont changé et que les types de données des deux dernières colonnes ont également changé comme spécifié.

Plusieurs ensembles de résultats

Certaines procédures stockées renvoient plusieurs jeux de résultats. Lors de l'utilisation de WITH RESULT SETS sur ces procédures, vous devez vous assurer que vous incluez des définitions pour chaque ensemble de résultats.

Vous ne pouvez pas simplement redéfinir certains mais pas les autres. Si vous faites cela, vous obtiendrez une erreur.

Si vous n'avez besoin de redéfinir qu'un seul ensemble de résultats, vous devez tous les redéfinir, même si leurs définitions restent identiques à leur définition d'origine.

Ce faisant, séparez chaque définition par une virgule.

Ensembles de résultats originaux

La procédure suivante renvoie trois ensembles de résultats.

EXEC sp_getCityStateCountryByCityId @CityId = 1;

Résultat :

+------------+----------------------------+-----------------------------+
| CityName   | LatestRecordedPopulation   | ValidFrom                   |
|------------+----------------------------+-----------------------------|
| Aaronsburg | 613                        | 2013-01-01 00:00:00.0000000 |
+------------+----------------------------+-----------------------------+
(1 row affected)
+---------------------+---------------------+----------------------------+
| StateProvinceCode   | StateProvinceName   | LatestRecordedPopulation   |
|---------------------+---------------------+----------------------------|
| PA                  | Pennsylvania        | 13284753                   |
+---------------------+---------------------+----------------------------+
(1 row affected)
+-----------------+---------------+----------------------------+
| IsoAlpha3Code   | CountryName   | LatestRecordedPopulation   |
|-----------------+---------------+----------------------------|
| USA             | United States | 313973000                  |
+-----------------+---------------+----------------------------+
(1 row affected)

Ensembles de résultats redéfinis

Nous pouvons redéfinir ces ensembles de résultats avec le code suivant.

EXEC sp_getCityStateCountryByCityId @CityId = 1
WITH RESULT SETS   
(  
    (
        [City] nvarchar(50),
        [Population] int,
        [Valid From] date
    ),
    (
        [State Code] nvarchar(5),
        [State Name] nvarchar(50),
        [Population] int
    ),
    (
        [Country Code] nvarchar(3),
        [Country Name] nvarchar(60),
        [Population] int
    )
);

Résultat :

+------------+--------------+--------------+
| City       | Population   | Valid From   |
|------------+--------------+--------------|
| Aaronsburg | 613          | 2013-01-01   |
+------------+--------------+--------------+
(1 row affected)
+--------------+--------------+--------------+
| State Code   | State Name   | Population   |
|--------------+--------------+--------------|
| PA           | Pennsylvania | 13284753     |
+--------------+--------------+--------------+
(1 row affected)
+----------------+----------------+--------------+
| Country Code   | Country Name   | Population   |
|----------------+----------------+--------------|
| USA            | United States  | 313973000    |
+----------------+----------------+--------------+
(1 row affected)

Réduction du nombre de colonnes renvoyées par la procédure stockée

Quand j'ai découvert le WITH RESULT SETS clause, j'étais excité, car je pensais que cela fournirait un moyen simple de réduire le nombre de colonnes renvoyées par la procédure stockée.

Malheureusement, ce n'est pas le cas.

Si vous n'incluez pas toutes les colonnes renvoyées par la procédure stockée dans votre WITH RESULT SETS clause, vous obtiendrez une erreur.

Cependant, tout n'est pas perdu. Voir Comment sélectionner un sous-ensemble de colonnes à partir d'une procédure stockée si vous voulez moins de colonnes que la procédure n'en renvoie.