Когато изпълнявате съхранена процедура, която връща набор от резултати в SQL Server, върнатите колони се дефинират в съхранената процедура.
Но знаете ли, че можете да предефинирате тези колони?
Имам предвид, че можете да промените имената и/или типа данни на колоните, върнати в набора от резултати.
Това може да ви спести от необходимостта да се занимавате със заглавките на колоните и форматите на данни в случай, че трябва да използвате този набор от резултати в друга настройка.
Например, ако съхранена процедура връща datetime2 колона, но ви трябва само частта за дата, можете да посочите дата за тази колона и вашият набор от резултати ще включва само частта за дата.
И най-хубавото е, че можете да го направите като част от EXECUTE
изявление. Няма нужда да масажирате данните след изпълнение на процедурата. начин да направите това е като използвате WITH RESULT SETS
клауза на EXECUTE
изявление.
Пример
Ето пример, за да демонстрирате как да използвате WITH RESULT SETS
клауза за промяна на имената на колоните и типовете данни от набора от резултати на съхранена процедура.
Необработени резултати
Първо, нека разгледаме суровите резултати от съхранена процедура.
EXEC sp_getCityById @CityId = 1;
Резултат:
+------------+----------------------------+-----------------------------+ | CityName | LatestRecordedPopulation | ValidFrom | |------------+----------------------------+-----------------------------| | Aaronsburg | 613 | 2013-01-01 00:00:00.0000000 | +------------+----------------------------+-----------------------------+
В зависимост от нашите изисквания, бихме искали процедурата да не използва толкова дълга колона за популацията (LatestRecordedPopulation
).
Може също така да пожелаем ValidFrom
колоната не включва времевата част, тъй като заема ненужно място и не е важна за нашата конкретна цел.
Може също да искаме да представим заглавките на колоните с интервал, само за да изглеждат малко по-представителни за този, на когото ще го изпратим.
Предфинирайте колоните
Сега нека да продължим и да използваме WITH RESULT SETS
клауза за предефиниране на колоните.
EXEC sp_getCityById @CityId = 1
WITH RESULT SETS
(
(
[City] nvarchar(50),
[Population] int,
[Valid From] date
)
);
Резултат:
+------------+--------------+--------------+ | City | Population | Valid From | |------------+--------------+--------------| | Aaronsburg | 613 | 2013-01-01 | +------------+--------------+--------------+
Така че с помощта на WITH RESULT SETS
клауза, успяхме да променим имената на колоните и типа данни.
Всъщност в този пример промених типа данни на последните две колони от bigint довх , и от datetime2(7) додатата , съответно.
Анализирайте наборите от резултати
Можем да използваме динамични изгледи за управление като sys.dm_exec_describe_first_result_set
и sys.dm_exec_describe_first_result_set_for_object
за да разберете действителните типове данни за всеки набор от резултати.
Ето пример за използване на sys.dm_exec_describe_first_result_set_for_object
за да получите имената на колоните и съответните им типове данни, върнати от съхранената процедура.
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);
Резултат:
+--------------------------+--------------------+--------------+-------------+---------+------------------+ | 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 | +--------------------------+--------------------+--------------+-------------+---------+------------------+
Това са действителните имена на колони и типове данни, върнати в резултатния набор (без да се предефинира нищо).
Виждаме, че последните две колони са големи и datetime2(7) съответно.
Сега нека използваме sys.dm_exec_describe_first_result_set
за да получите метаданните за нашата модифицирана заявка.
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
);
Резултат:
+------------+--------------------+--------------+-------------+---------+------------------+ | 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 | +------------+--------------------+--------------+-------------+---------+------------------+
Така можем да видим, че имената на колоните са се променили и типовете данни на последните две колони също са се променили, както е посочено.
Множество набори от резултати
Някои съхранени процедури връщат множество набори от резултати. При използване на WITH RESULT SETS
при тези процедури трябва да се уверите, че сте включили дефиниции за всеки набор от резултати.
Не можете просто да предефинирате някои, но не и други. Ако направите това, ще получите грешка.
Ако трябва да предефинирате само един набор от резултати, трябва да ги направите всички – дори и техните дефиниции да останат същите като оригиналната им дефиниция.
Когато правите това, отделете всяко определение със запетая.
Оригинални набори от резултати
Следната процедура връща три набора резултати.
EXEC sp_getCityStateCountryByCityId @CityId = 1;
Резултат:
+------------+----------------------------+-----------------------------+ | 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)
Предефинирани набори от резултати
Можем да предефинираме тези набори от резултати със следния код.
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
)
);
Резултат:
+------------+--------------+--------------+ | 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)
Намаляване на броя на колоните, върнати от съхранената процедура
Когато за първи път разбрах за WITH RESULT SETS
клауза, бях развълнуван, защото мислех, че ще осигури лесен начин за намаляване на броя на колоните, върнати от съхранената процедура.
За съжаление, това не е така.
Ако не включите всички колони, върнати от съхранената процедура във вашия WITH RESULT SETS
клауза, ще получите грешка.
Не всичко обаче е загубено. Вижте Как да изберете подмножество от колони от съхранена процедура, ако искате по-малко колони, отколкото процедурата връща.