SqlHelper类调用存储过程的方法有下面类似的两种类型:
/// <param name="connectionString">A valid connection string for a SqlConnection</param>
/// <param name="commandType">The CommandType (stored procedure, text, etc.)</param>
/// <param name="commandText">The stored procedure name or T-SQL command</param>
/// <param name="commandParameters">An array of SqlParamters used to execute the command</param>
/// <returns>An int representing the number of rows affected by the command</returns>
1、public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
/// <remarks>
/// This method provides no access to output parameters or the stored procedure's return value parameter.
</remarks>
2、public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues)
第一种方法调用存储过程是可以获得存储过程返回值的
第二种方法调用存储过程是获取不了返回值和输出参数的
原因:
仔细看的里面的实现将会发现:
它调用了:GetSpParameterSet(connection, spName, false);
接着调用:GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter);
在GetSpParameterSetInternal里面有这样的判断:
string hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter":"");
很显然没有返回值,然后在DiscoverSpParameterSet方法内通过
if (!includeReturnValueParameter)
{
cmd.Parameters.RemoveAt(0);//由于自动检测参数时, 会在参数列表的首项加入@Return_Value.如果不需要它时,就要移去
}
消除返回参数。其实由于第二种方法传递的是object类型的数据进去,根本就没有把需要返回参数返回值这种信息传递进去,程序无法知道你是不是需要返回参数的值。而且object类型是值类型,函数内改变它的值也带不回来。
之所以会有第二种调用方法是为了我们能更方便的调用存储过程,不必去关系存储过程参数名是什么,知道它的参数顺序就可以了,它主要是利用SqlCommandBuilder.DeriveParameters(cmd);来获取参数信息的,利用hashtable保存了Parameters。(为什么要用hashtable来保存,不保存应该也可以行的通的,还是从hashtable 里才clone一份Parameters出来用的。用静态的hashtable存储了最近一次调用的SqlParameter ,如果下次还是同一次调用,速度会快一些,不用去SqlCommandBuilder.DeriveParameters了,少连一次数据库)第一种方法显然是要麻烦很多,要创建 SqlParameter 对象,还要注意存储过程参数名称等问题。下面是第一种方法调用例子:
{
SqlParameter[] ParamList = {
SqlHelper.MakeInParam( " @BrandName " ,SqlDbType.VarChar, 32 ,brand.BrandName),
SqlHelper.MakeRetParam( " @Ret " ,SqlDbType.Int, 4 )
};
SqlConnection connection = new SqlConnection(DbConn.ConnectString);
try
{
SqlHelper.ExecuteNonQuery(connection, CommandType.StoredProcedure, " SP_Brand_Insert " , ParamList);
return Int32.Parse(ParamList[ 1 ].Value.ToString());
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
finally
{
connection.Close();
connection.Dispose();
}
}
输出参数的问题:
当 Command 对象用于存储过程时,可以将 Command 对象的 CommandType 属性设置为 StoredProcedure。当 CommandType 为 StoredProcedure 时,可以使用 Command 的 Parameters 属性来访问输入及输出参数和返回值。无论调用哪一个 Execute 方法,都可以访问 Parameters 属性。但是,当调用 ExecuteReader 时,在 DataReader 关闭之前,将无法访问返回值和输出参数。下面是个例子:
{
SqlParameter[] ParamList = {
SqlHelper.MakeInParam( " @CurrentPage " ,SqlDbType.Int, 4 ,currentPage),
SqlHelper.MakeInParam( " @PageSize " ,SqlDbType.Int, 4 ,pageSize),
SqlHelper.MakeOutParam( " @RecordCount " ,SqlDbType.Int, 4 )
};
SqlConnection connection = new SqlConnection(DbConn.ConnectString);
SqlDataReader dr = null ;
try
{
dr = SqlHelper.ExecuteReader(connection, CommandType.StoredProcedure, " SP_Clothes_GetAll_Page " , ParamList);
List < Clothes > listClothes = new List < Clothes > ();
while (dr.Read())
{
Clothes c = new Clothes();
c.ClothesId = Int64.Parse(dr[ " ClothesId " ].ToString());
c.ClothesName = dr[ " ClothesName " ] == null ? null : dr[ " ClothesName " ].ToString();
c.ClothesNums = dr[ " ClothesNums " ].ToString();
if (dr[ " ClothesSex " ].ToString() == " 男 " ) c.ClothesSex = 1 ;
if (dr[ " ClothesSex " ].ToString() == " 女 " ) c.ClothesSex = 0 ;
c.CBrand = new Brand() { BrandId = byte .Parse(dr[ " BrandId " ].ToString()), BrandName = dr[ " BrandName " ].ToString() };
c.CStyle = new Style() { StyleId = byte .Parse(dr[ " StyleId " ].ToString()), StyleName = dr[ " StyleName " ].ToString() };
c.CSeason = new Season() { SeasonId = byte .Parse(dr[ " SeasonId " ].ToString()), SeasonName = dr[ " SeasonName " ].ToString() };
c.CPattern = new Pattern() { PatternId = byte .Parse(dr[ " PatternId " ].ToString()), PatternName = dr[ " PatternName " ].ToString() };
c.CClass = new Class() { ClassId = byte .Parse(dr[ " ClassId " ].ToString()), ClassName = dr[ " ClassName " ].ToString() };
c.SmallPic = ( byte [])dr[ " SmallPic " ];
c.ShowPic = ( byte [])dr[ " ShowPic " ];
c.Memo = dr[ " Memo " ].ToString();
listClothes.Add(c);
}
dr.Close();
dr.Dispose();
rowsCount = Int32.Parse(ParamList[ 2 ].Value.ToString());
return listClothes;
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
finally
{
connection.Close();
connection.Dispose();
}
}