存储过程中返回结果集是很常见的,但如果想要控制部分返回结果集的字段名和数据类型将会是很困难的。SQL Server 2012(版本代号为Denali)引入一个新特性WITH RESULT SETS,可以重新定义存储过程中返回结果的字段名和数据类型。本文将详细的介绍这一新特性。

  认识WITH RESULT SETS子句

  SQL Server 2012(版本代号为Denali)引入EXECUTE语句中的WITH RESULT SETS子句,可以重新定义从存储过程中返回结果的字段名和数据类型。这会使得向拥有特定字段名和数据类型的临时表的结果集中插入记录将变得非常容易,并且不需要依赖存储过程返回了哪些内容。

  WITH RESULT SETS子句同样可以使用在存储过程中,存储过程会返回大量结果集,并且每个结果集都可以自定义各自的字段名和数据类型。

  请注意:

  ·通常情况下,如果想要限制存储过程返回一个结果集,可以使用RESULT SETS NONE子句。

  ·INSERT…EXEC语句中不能指定WITH RESULT SETS选项。

  ·返回列的数量作为结果集的一部分不会改变。

  理论已经足够了,下面围绕这一新特性亲自动手操作一下吧:

  WITH RESULT SETS子句用法实例

  在下面的实例中,首先新建一个表格并插入一些数据,然后创建存储过程——从表中查询数据并返回结果集。如果使用“EXECUTE GetEmployees call”,则返回的结果集的字段名和数据类型是存储过程中的特定格式,就不能控制并改变它。最后是使用了WITH RESULT SETS子句的“EXECUTE GetEmployees call”,可以对返回结果集的字段进行重命名字段名操作并定义不同的数据类型(只能是相互兼容的数据类型):

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Employee]')   AND type in (N'U'))
       DROP TABLE [dbo].[Employee]
GO
CREATE TABLE [dbo].[Employee]
(
        [EmpId]   [INT]   NOT NULL IDENTITY PRIMARY KEY,
        [FirstName]  NVARCHAR(100) NOT NULL,
        [MiddleName]  NVARCHAR(100)  NULL,
        [LastName]  NVARCHAR(100)  NOT NULL,
)
GO
INSERT INTO [dbo].[Employee] (FirstName, MiddleName, LastName)
VALUES
       ('Arshad', NULL,'Ali'),
       ('Paul', 'M','John')
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetEmployees]')   AND type in (N'P', N'PC'))
       DROP PROCEDURE [dbo].[GetEmployees]
GO
CREATE PROCEDURE GetEmployees
AS
BEGIN
SELECT EmpId, FirstName + ' ' + ISNULL(MiddleName, '') +' '+ LastName AS Name
FROM dbo.Employee
END
GO
EXECUTE   GetEmployees
GO
EXECUTE   GetEmployees
WITH RESULT SETS
(
       (
       EmployeeId INT,
       EmployeeName VARCHAR(150)
       )
)
GO
 

▲图1. 单一结果集的WITH RESULT SETS实例

  就像我之前所说的那样,不只是返回单一结果集的存储过程可以使用WITH RESULT SETS子句,如上图所示,返回多重结果集的存储过程也同样适用,如下代码所示。下面的实例中存储过程返回两个结果集,每个结果集的每一列的字段名和数据类型可以分别进行重新定义。

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetEmployeesWithMultipleResultsets]') AND type in (N'P', N'PC'))
       DROP PROCEDURE [dbo].[GetEmployeesWithMultipleResultsets]
GO
CREATE PROCEDURE GetEmployeesWithMultipleResultsets
AS
BEGIN
SELECT EmpId, FirstName + ' ' + ISNULL(MiddleName, '') +' '+ LastName AS Name
FROM dbo.Employee
    SELECT EmpId, FirstName + ' ' + ISNULL(MiddleName, '') +' '+ LastName AS Name
FROM dbo.Employee
END
GO
EXEC GetEmployeesWithMultipleResultsets
GO
EXECUTE   GetEmployeesWithMultipleResultsets
WITH RESULT SETS
(
       (
       EmployeeId1 INT,
       EmployeeName1 VARCHAR(150)
       ),
       (
       EmployeeId2 INT NOT NULL,
       EmployeeFullName2 VARCHAR(150) NOT NULL
       )
)
GO
 SQL Server2012新特性WITH RESULT SETS
 

▲图2. 多重结果集的WITH RESULT SETS实例

  结论

  本文介绍了SQL Server 2012的结果集新特性——WITH RESULT SETS,它可以同EXECUTE语句一起用来重新定义存储过程返回结果集的字段名和数据类型。这一新特性同样可以用来分别重新定义/格式化存储过程返回的多重结果集的字段名和数据类型。