存储过程中可以定义输出变量,返回值,执行存储过程还能获得结果集。每个存储过程的默认返回值为0。下面紧接着上文 SQL Server中存储过程Stored Procedure创建及C#调用 基础上写的一个新的Stored Procedure存储过程则包含了输出参数、返回值以及select结果。
USE [db]
GO
/****** Object: StoredProcedure [dbo].[insert_persions] Script Date: 2/25/2015 11:14:11 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF OBJECT_ID (‘get_persons‘,‘p‘) IS NOT NULL
DROP PROCEDURE get_persons;
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE PROCEDURE get_persons
-- Add the parameters for the stored procedure here
@firstname varchar(255),
@ret int = 0 OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT * FROM Persons
WHERE FirstName = @firstname;
SET @ret = @@ROWCOUNT
RETURN 10
END
GO
DECLARE @retVal int, @status int
EXECUTE @status = get_persons "San",@ret = @retVal OUTPUT
SELECT @retVal as N‘Output val‘,@status as N‘Ruturn val‘
输出参数
输出参数的定义位置和存储过程的一般参数一样,只不过会在后面增加一个OUTPUT关键字。在过程体中然后给参数使用SET指定输出值。
执行包含输出参数得到过程体的SQL语句中,也需要先定义变量,再将变量作为参数传入执行语句中同时加上OUTPUT。如上例子所示:EXECUTE get_persons “San”,@ret = @retVal OUTPUT
返回值
存储过程一般会有默认的返回值为0,但是我们也可以在过程体要结束的位置或者某个分支块结束语句处加上RETURN VALUE语句。
执行过程体的时候,如果需要同时获取得到的返回值,可以先定义变量,再使用“变量=”放在EXECUTE后面从而获得执行结果值。例子就是:EXECUTE @status = get_persons “San”,@ret = @retVal OUTPUT
上述例子中的存储过程语句在SQL Server Management Studio执行完毕后,会每个select语句生成一个Table结果,如下图所示:
C#调用
上面例子中给出了SQL语句应对输出参数、返回值及SELECT表的情况。如果我们需要用C#来执行存储过程同时也希望得到所有的这些结果,可以按如下代码来:
String conStr = @"Data Source=HOST\SQLEXPRESS;Initial Catalog=DB;Integrated Security=SSPI";
SqlConnection con = new SqlConnection(conStr);
try
{
con.Open();
Console.WriteLine("Connect Sucess!");
SqlCommand com = new SqlCommand();
com.CommandType = System.Data.CommandType.StoredProcedure;
com.Connection = con;
com.CommandText = "get_persons";
SqlParameter pFirstName = new SqlParameter("@firstname", "San");
SqlParameter para = new SqlParameter("@ret", SqlDbType.Int);
para.Direction = ParameterDirection.Output;
com.Parameters.Add(pFirstName);
com.Parameters.Add(para);
com.Parameters.Add("@status", SqlDbType.Int);
com.Parameters["@status"].Direction = ParameterDirection.ReturnValue;
SqlDataReader sdr = com.ExecuteReader();
while (sdr.Read())
{
for (int i = 0; i < sdr.FieldCount; i++)
Console.Write(sdr[i].ToString() + " ");
Console.WriteLine();
}
sdr.Close();
Console.WriteLine(com.Parameters["@ret"].Value);
Console.WriteLine(com.Parameters["@status"].Value);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
con.Close();
}
从中我们可以看出,对于输出参数和返回值,都是增加与存储过程一样的参数名及类型,同时指定ParameterDirection,分别为OUTPUT和RETURNVALUE。而获取执行结果则可以再命令执行完毕后获取命令参数的值“com.Parameters[“@ret”].Value”。
对于无需获取SELECT结果的情况,我们可以直接用命令ExecuteNonQuery即可。可是如果我们还想得到存储过程执行所得到的表结果呢?这时候一个办法是利用“SqlDataReader sdr = com.ExecuteReader();”执行然后通过sdr.Read()来读取SELECT结果。这里需要注意的是,根据个人实践,sdr读完需要关系后才能够获取到返回参数及返回值。