Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come ridefinire le colonne restituite da una stored procedure in SQL Server

Quando si esegue una stored procedure che restituisce un set di risultati in SQL Server, le colonne restituite vengono definite nella stored procedure.

Ma lo sapevi che puoi ridefinire quelle colonne?

Quello che voglio dire è che puoi cambiare i nomi e/o il tipo di dati delle colonne restituite nel set di risultati.

Ciò potrebbe evitarti di dover armeggiare con le intestazioni delle colonne e i formati dei dati nel caso in cui dovessi utilizzare quel set di risultati in un'altra impostazione.

Ad esempio, se una stored procedure restituisce un datetime2 colonna, ma ti serve solo la parte della data, puoi specificare data per quella colonna e il tuo set di risultati includerà solo la parte della data.

E la parte migliore è che puoi farlo come parte di EXECUTE dichiarazione. Non c'è bisogno di massaggiare i dati dopo aver eseguito la procedura. il modo per farlo è usare WITH RESULT SETS clausola del EXECUTE dichiarazione.

Esempio

Ecco un esempio per dimostrare come utilizzare WITH RESULT SETS clausola per modificare i nomi delle colonne e i tipi di dati dal set di risultati di una procedura memorizzata.

Risultati grezzi

Innanzitutto, diamo un'occhiata ai risultati grezzi di una procedura memorizzata.

EXEC sp_getCityById @CityId = 1;

Risultato:

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

A seconda dei nostri requisiti, potremmo desiderare che la procedura non utilizzasse un'intestazione di colonna così lunga per la popolazione (LatestRecordedPopulation ).

Potremmo anche desiderare che il ValidFrom la colonna non includeva la parte temporale, poiché occupa spazio non necessario e non è importante per il nostro scopo particolare.

Potremmo anche presentare le intestazioni delle colonne con uno spazio, solo per renderlo leggermente più presentabile per chiunque sia a cui lo invieremo.

Rifinisci le colonne

Ora andiamo avanti e usiamo il WITH RESULT SETS clausola per ridefinire le colonne.

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

Risultato:

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

Quindi, usando il WITH RESULT SETS clausola, siamo stati in grado di modificare i nomi delle colonne e il tipo di dati.

In realtà, in questo esempio ho cambiato il tipo di dati delle ultime due colonne da bigint a int e da datetime2(7) a data , rispettivamente.

Analizza i set di risultati

Possiamo utilizzare viste a gestione dinamica come sys.dm_exec_describe_first_result_set e sys.dm_exec_describe_first_result_set_for_object per scoprire i tipi di dati effettivi di ciascun set di risultati.

Ecco un esempio di utilizzo di sys.dm_exec_describe_first_result_set_for_object per ottenere i nomi delle colonne ei rispettivi tipi di dati restituiti dalla procedura memorizzata.

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

Risultato:

+--------------------------+--------------------+--------------+-------------+---------+------------------+
| 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             |
+--------------------------+--------------------+--------------+-------------+---------+------------------+

Quindi questi sono i nomi di colonna e i tipi di dati effettivi restituiti nel set di risultati (senza ridefinire nulla).

Possiamo vedere che le ultime due colonne sono bigint e datetime2(7) rispettivamente.

Ora usiamo sys.dm_exec_describe_first_result_set per ottenere i metadati per la nostra query modificata.

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

Risultato:

+------------+--------------------+--------------+-------------+---------+------------------+
| 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             |
+------------+--------------------+--------------+-------------+---------+------------------+

Quindi possiamo vedere che i nomi delle colonne sono cambiati e anche i tipi di dati delle ultime due colonne sono cambiati come specificato.

Insiemi di risultati multipli

Alcune stored procedure restituiscono più set di risultati. Quando si utilizza WITH RESULT SETS su queste procedure, devi assicurarti di includere le definizioni per ogni set di risultati.

Non puoi semplicemente ridefinire alcuni ma non gli altri. Se lo fai, riceverai un errore.

Se devi ridefinire un solo set di risultati, devi eseguirli tutti, anche se le loro definizioni rimangono le stesse della loro definizione originale.

Quando fai ciò, separa ogni definizione con una virgola.

Set di risultati originali

La procedura seguente restituisce tre set di risultati.

EXEC sp_getCityStateCountryByCityId @CityId = 1;

Risultato:

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

Insiemi di risultati ridefiniti

Possiamo ridefinire questi set di risultati con il codice seguente.

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

Risultato:

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

Ridurre il numero di colonne restituite dalla stored procedure

Quando ho scoperto per la prima volta il WITH RESULT SETS clausola, ero entusiasta, perché pensavo che avrebbe fornito un modo semplice per ridurre il numero di colonne restituite dalla stored procedure.

Purtroppo, non è così.

Se non includi tutte le colonne restituite dalla stored procedure nel tuo WITH RESULT SETS clausola, riceverai un errore.

Tuttavia, non tutto è perduto. Vedere Come selezionare un sottoinsieme di colonne da una stored procedure se si desidera un numero di colonne inferiore a quello restituito dalla procedura.