sql >> Database >  >> RDS >> Sqlserver

Hoe de kolommen opnieuw te definiëren die worden geretourneerd door een opgeslagen procedure in SQL Server

Wanneer u een opgeslagen procedure uitvoert die een resultaatset in SQL Server retourneert, worden de geretourneerde kolommen gedefinieerd in de opgeslagen procedure.

Maar wist je dat je die kolommen opnieuw kunt definiëren?

Wat ik bedoel is dat je de namen en/of het gegevenstype van de kolommen die in de resultatenset worden geretourneerd, kunt wijzigen.

Dit kan voorkomen dat u moet knoeien met de kolomkoppen en gegevensindelingen voor het geval u die resultatenset in een andere instelling zou moeten gebruiken.

Als een opgeslagen procedure bijvoorbeeld een datetime2 . retourneert kolom, maar je hebt alleen het datumgedeelte nodig, je zou datum kunnen specificeren voor die kolom, en uw resultatenset bevat alleen het datumgedeelte.

En het beste is dat je het kunt doen als onderdeel van de EXECUTE uitspraak. Het is niet nodig om de gegevens te masseren na het uitvoeren van de procedure. manier om dit te doen is met behulp van de WITH RESULT SETS clausule van de EXECUTE verklaring.

Voorbeeld

Hier is een voorbeeld om te demonstreren hoe de WITH RESULT SETS . te gebruiken clausule om de kolomnamen en gegevenstypen uit de resultatenset van een opgeslagen procedure te wijzigen.

Ruwe resultaten

Laten we eerst eens kijken naar de onbewerkte resultaten van een opgeslagen procedure.

EXEC sp_getCityById @CityId = 1;

Resultaat:

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

Afhankelijk van onze vereisten, zouden we kunnen wensen dat de procedure niet zo'n lange kolomkop voor de populatie gebruikte (LatestRecordedPopulation ).

We zouden ook willen dat de ValidFrom kolom bevatte het tijdsgedeelte niet, omdat het onnodige ruimte in beslag neemt en het niet belangrijk is voor ons specifieke doel.

We willen misschien ook de kolomkoppen voorzien van een spatie, zodat het er iets presentabeler uitziet voor degene naar wie we het sturen.

De kolommen opnieuw verfijnen

Laten we nu doorgaan en de WITH RESULT SETS . gebruiken clausule om de kolommen opnieuw te definiëren.

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

Resultaat:

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

Dus door gebruik te maken van de WITH RESULT SETS clausule, konden we de kolomnamen en het gegevenstype wijzigen.

In dit voorbeeld heb ik het gegevenstype van de laatste twee kolommen gewijzigd van bigint naar int , en vanaf datetime2(7) tot datum , respectievelijk.

De resultatensets analyseren

We kunnen dynamische beheerweergaven gebruiken, zoals sys.dm_exec_describe_first_result_set en sys.dm_exec_describe_first_result_set_for_object om de feitelijke gegevenstypen van elke resultaatset te achterhalen.

Hier is een voorbeeld van het gebruik van sys.dm_exec_describe_first_result_set_for_object om de kolomnamen en hun respectievelijke gegevenstypes terug te krijgen door de opgeslagen procedure.

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

Resultaat:

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

Dit zijn dus de daadwerkelijke kolomnamen en gegevenstypen die in de resultatenset worden geretourneerd (zonder iets opnieuw te definiëren).

We kunnen zien dat de laatste twee kolommen groot zijn en datetime2(7) respectievelijk.

Laten we nu sys.dm_exec_describe_first_result_set gebruiken om de metadata voor onze aangepaste zoekopdracht te krijgen.

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

Resultaat:

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

We kunnen dus zien dat de kolomnamen zijn gewijzigd en dat de gegevenstypen van de laatste twee kolommen ook zijn gewijzigd zoals gespecificeerd.

Meerdere resultatensets

Sommige opgeslagen procedures retourneren meerdere resultaatsets. Bij gebruik van WITH RESULT SETS bij deze procedures moet u ervoor zorgen dat u definities opneemt voor elke resultaatset.

Sommige kun je niet zomaar herdefiniëren, andere niet. Als je dat doet, krijg je een foutmelding.

Als u slechts één resultatenset opnieuw hoeft te definiëren, moet u ze allemaal doen, zelfs als hun definities hetzelfde blijven als hun oorspronkelijke definitie.

Scheid daarbij elke definitie met een komma.

Originele resultatensets

De volgende procedure levert drie resultaatsets op.

EXEC sp_getCityStateCountryByCityId @CityId = 1;

Resultaat:

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

Opnieuw gedefinieerde resultatensets

We kunnen deze resultatensets opnieuw definiëren met de volgende code.

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

Resultaat:

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

Het aantal kolommen verminderen dat wordt geretourneerd door de opgeslagen procedure

Toen ik voor het eerst hoorde over de WITH RESULT SETS clausule, was ik enthousiast, omdat ik dacht dat het een eenvoudige manier zou zijn om het aantal kolommen te verminderen dat door de opgeslagen procedure wordt geretourneerd.

Helaas is dat niet het geval.

Als u niet alle kolommen opneemt die door de opgeslagen procedure worden geretourneerd in uw WITH RESULT SETS clausule, krijg je een foutmelding.

Alles is echter niet verloren. Zie Een subset van kolommen selecteren uit een opgeslagen procedure als u minder kolommen wilt dan de procedure retourneert.


  1. Verborgen functies van PostgreSQL

  2. De opgeslagen procedure om de instantie-instellingen op te halen

  3. TEXTSIZE INSTELLEN Werkt niet in SQL Server? Controleer dit.

  4. Hoe voer ik databasetransacties uit met psycopg2/python db api?