sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man omdefinierar kolumner som returneras av en lagrad procedur i SQL Server

När du kör en lagrad procedur som returnerar en resultatuppsättning i SQL Server, definieras kolumnerna som returneras i den lagrade proceduren.

Men visste du att du kan omdefiniera dessa kolumner?

Vad jag menar är att du kan ändra namnen och/eller datatypen för kolumnerna som returneras i resultatuppsättningen.

Detta kan rädda dig från att behöva pilla med kolumnrubriker och dataformat om du behövde använda den resultatuppsättningen i en annan inställning.

Till exempel, om en lagrad procedur returnerar en datetime2 kolumnen, men du behöver bara datumdelen, du kan ange datum för den kolumnen, och din resultatuppsättning kommer bara att inkludera datumdelen.

Och det bästa är att du kan göra det som en del av EXECUTE påstående. Inget behov av att massera data efter att ha utfört proceduren. sättet att göra detta är genom att använda WITH RESULT SETS satsen i EXECUTE uttalande.

Exempel

Här är ett exempel för att visa hur du använder WITH RESULT SETS sats för att ändra kolumnnamn och datatyper från resultatuppsättningen av en lagrad procedur.

Råresultat

Låt oss först titta på de råa resultaten från en lagrad procedur.

EXEC sp_getCityById @CityId = 1;

Resultat:

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

Beroende på våra krav kanske vi önskar att proceduren inte använde en så lång kolumnrubrik för populationen (LatestRecordedPopulation ).

Vi kanske också önskar att ValidFrom kolumnen inkluderade inte tidsdelen, eftersom den tar onödigt utrymme och den är inte viktig för vårt specifika syfte.

Vi kanske också vill presentera kolumnrubrikerna med ett mellanslag, bara för att få det att se lite mer presentabelt ut för vem det än är som vi skickar det till.

Omfiniera kolumnerna

Låt oss nu gå vidare och använda WITH RESULT SETS sats för att omdefiniera kolumnerna.

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

Resultat:

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

Så genom att använda WITH RESULT SETS klausul kunde vi ändra kolumnnamnen och datatypen.

I det här exemplet ändrade jag faktiskt datatypen för de två sista kolumnerna från bigint till int och från datetime2(7) till datum , respektive.

Analysera resultatuppsättningarna

Vi kan använda dynamiska hanteringsvyer som sys.dm_exec_describe_first_result_set och sys.dm_exec_describe_first_result_set_for_object för att ta reda på de faktiska datatyperna för varje resultatuppsättning.

Här är ett exempel på hur du använder sys.dm_exec_describe_first_result_set_for_object för att få kolumnnamnen och deras respektive datatyper returnerade av den lagrade proceduren.

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

Resultat:

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

Så dessa är de faktiska kolumnnamnen och datatyperna som returneras i resultatuppsättningen (utan att omdefiniera någonting).

Vi kan se att de två sista kolumnerna är stora och datetime2(7) respektive.

Låt oss nu använda sys.dm_exec_describe_first_result_set för att få metadata för vår modifierade fråga.

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

Resultat:

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

Så vi kan se att kolumnnamnen har ändrats, och datatyperna för de två senaste kolumnerna har också ändrats enligt vad som anges.

Flera resultatuppsättningar

Vissa lagrade procedurer returnerar flera resultatuppsättningar. När du använder WITH RESULT SETS i dessa procedurer måste du se till att du inkluderar definitioner för varje resultatuppsättning.

Du kan inte bara omdefiniera vissa men inte andra. Om du gör det får du ett felmeddelande.

Om du bara behöver omdefiniera en resultatuppsättning måste du göra dem alla – även om deras definitioner förblir desamma som deras ursprungliga definition.

När du gör detta, separera varje definition med ett kommatecken.

Ursprungliga resultatuppsättningar

Följande procedur returnerar tre resultatuppsättningar.

EXEC sp_getCityStateCountryByCityId @CityId = 1;

Resultat:

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

Omdefinierade resultatuppsättningar

Vi kan omdefiniera dessa resultatuppsättningar med följande kod.

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

Resultat:

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

Minska antalet kolumner som returneras av den lagrade proceduren

När jag först fick reda på WITH RESULT SETS klausul, jag var exalterad, eftersom jag trodde att det skulle vara ett enkelt sätt att minska antalet kolumner som returneras av den lagrade proceduren.

Tyvärr är så inte fallet.

Om du inte inkluderar alla kolumner som returneras av den lagrade proceduren i din WITH RESULT SETS klausul får du ett felmeddelande.

Allt är dock inte förlorat. Se Hur man väljer en delmängd av kolumner från en lagrad procedur om du vill ha färre kolumner än vad proceduren returnerar.


  1. Använd molnformationsmallar för att spinna upp MySQL-instanser på RDS

  2. Vad är standardbegränsningsnamnet i PostgreSQL?

  3. MIN och MAX samlade funktioner i SQL Server

  4. VALUES-uttalande i MySQL