Når du udfører en lagret procedure, der returnerer et resultatsæt i SQL Server, defineres de returnerede kolonner i den lagrede procedure.
Men vidste du, at du kan omdefinere disse kolonner?
Det, jeg mener, er, at du kan ændre navnene og/eller datatypen for de kolonner, der returneres i resultatsættet.
Dette kan spare dig for at skulle rode med kolonneoverskrifterne og dataformaterne, hvis du skulle bruge dette resultatsæt i en anden indstilling.
For eksempel, hvis en lagret procedure returnerer en datetime2 kolonne, men du behøver kun datodelen, kan du angive dato for den kolonne, og dit resultatsæt vil kun inkludere datodelen.
Og det bedste er, at du kan gøre det som en del af EXECUTE
udmelding. Ingen grund til at massere dataene efter at have udført proceduren. måde at gøre dette på er ved at bruge WITH RESULT SETS
klausul af EXECUTE
erklæring.
Eksempel
Her er et eksempel til at demonstrere, hvordan man bruger WITH RESULT SETS
klausul for at ændre kolonnenavne og datatyper fra resultatsættet af en lagret procedure.
Rå resultater
Lad os først se på de rå resultater fra en lagret procedure.
EXEC sp_getCityById @CityId = 1;
Resultat:
+------------+----------------------------+-----------------------------+ | CityName | LatestRecordedPopulation | ValidFrom | |------------+----------------------------+-----------------------------| | Aaronsburg | 613 | 2013-01-01 00:00:00.0000000 | +------------+----------------------------+-----------------------------+
Afhængigt af vores krav kunne vi ønske, at proceduren ikke brugte så lang en kolonneoverskrift for populationen (LatestRecordedPopulation
).
Vi ønsker måske også, at ValidFrom
kolonnen indeholdt ikke tidsdelen, da den optager unødvendig plads, og den er ikke vigtig for vores særlige formål.
Vi vil måske også præsentere kolonneoverskrifterne med et mellemrum, bare for at få det til at se lidt mere præsentabelt ud for hvem det end er, vi sender det til.
Omdefiner kolonnerne
Lad os nu gå videre og bruge WITH RESULT SETS
klausul for at omdefinere kolonnerne.
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å ved at bruge WITH RESULT SETS
klausul, var vi i stand til at ændre kolonnenavnene og datatypen.
Faktisk ændrede jeg i dette eksempel datatypen for de sidste to kolonner fra bigint til int , og fra datetime2(7) til dato hhv.
Analyser resultatsættene
Vi kan bruge dynamiske administrationsvisninger såsom sys.dm_exec_describe_first_result_set
og sys.dm_exec_describe_first_result_set_for_object
for at finde ud af de faktiske datatyper for hvert resultatsæt.
Her er et eksempel på brug af sys.dm_exec_describe_first_result_set_for_object
for at få kolonnenavnene og deres respektive datatyper returneret af den lagrede 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);
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å disse er de faktiske kolonnenavne og datatyper, der returneres i resultatsættet (uden at omdefinere noget).
Vi kan se, at de sidste to kolonner er store og datetime2(7) hhv.
Lad os nu bruge sys.dm_exec_describe_first_result_set
for at få metadataene til vores ændrede forespørgsel.
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, at kolonnenavnene er ændret, og datatyperne for de sidste to kolonner er også ændret som angivet.
Flere resultatsæt
Nogle lagrede procedurer returnerer flere resultatsæt. Når du bruger WITH RESULT SETS
på disse procedurer skal du sikre dig, at du inkluderer definitioner for hvert resultatsæt.
Du kan ikke bare omdefinere nogle, men ikke de andre. Hvis du gør det, får du en fejl.
Hvis du kun skal omdefinere ét resultatsæt, skal du gøre dem alle – også selvom deres definitioner forbliver de samme som deres oprindelige definition.
Når du gør dette, skal du adskille hver definition med et komma.
Originale resultatsæt
Følgende procedure returnerer tre resultatsæt.
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)
Omdefinerede resultatsæt
Vi kan omdefinere disse resultatsæt med følgende kode.
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)
Reduktion af antallet af kolonner, der returneres af den lagrede procedure
Da jeg første gang fandt ud af WITH RESULT SETS
klausul, jeg var spændt, fordi jeg troede, at det ville være en enkel måde at reducere antallet af kolonner, der returneres af den lagrede procedure.
Det er desværre ikke tilfældet.
Hvis du ikke inkluderer alle de kolonner, der returneres af den lagrede procedure i din WITH RESULT SETS
klausul, får du en fejl.
Alt er dog ikke tabt. Se, hvordan du vælger et undersæt af kolonner fra en lagret procedure, hvis du ønsker færre kolonner, end proceduren returnerer.