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.