由于MYSQL或MSSQL存储过程参数不确定,一般情况下.net 调用存储过程时需针对具体存储过程写不同的调用方法。 本文通过实现先调用系统表中存储过程参数列表,针对参数名称、类型、精度、长度等,动态生成存储过程调用参数,为通用的存储过程调用提供方便。注意类型转换部分要仔细自行验证,确保转换正确。用于MSSQL时类型转换有所不同。
/// <summary>
/// 获取存储过程的参数,生成存储过程调用参数列表
/// </summary>
/// <param name="ProcedureName">存储过程名称</param>
/// <param name="parameters">存储过程调用参数值集合</param>
/// <returns></returns>
private MySqlParameter[] GetMySQLParameters(string ProcedureName, object[] parameters)
{
DataTable dt = new DataTable();
string sqlString = "select * from INFORMATION_SCHEMA.PARAMETERS where SPECIFIC_NAME='" + ProcedureName + "' order by ORDINAL_POSITION";
if (!Select(sqlString, dt))
return null;
List<MySqlParameter> sqlParameters = new List<MySqlParameter>();
for (int i = 0; i < dt.Rows.Count; i++)
{
MySqlParameter sqlParameter = new MySqlParameter();
sqlParameter.ParameterName = dt.Rows[i]["PARAMETER_NAME"].ToString();
sqlParameter.Direction = (dt.Rows[i]["PARAMETER_MODE"].ToString() == "IN") ? ParameterDirection.Input : ParameterDirection.Output;
#region 匹配参数类型
switch (dt.Rows[i]["DATA_TYPE"].ToString().ToLower ())
{
case "bit":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = (bool)(parameters[i]);
sqlParameter.MySqlDbType = MySqlDbType.Bit;
break;
case "int64":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = Convert.ToInt64(parameters[i]);
sqlParameter.MySqlDbType = MySqlDbType.Int64;
break;
case "int":
case "int32":
if (sqlParameter.Direction == ParameterDirection.Input)
if (parameters[i] == DBNull.Value)//参数为DBNull时
{
sqlParameter.Value = DBNull.Value;
}
else
{
sqlParameter.Value = Convert.ToInt32(parameters[i]);
}
sqlParameter.MySqlDbType = MySqlDbType.Int32;
break;
case "decimal":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = Convert.ToDecimal(parameters[i]);
sqlParameter.MySqlDbType = MySqlDbType.Decimal;
sqlParameter.Precision = Convert.ToByte(dt.Rows[i]["NUMERIC_PRECISION"]);
sqlParameter.Scale = Convert.ToByte(dt.Rows[i]["NUMERIC_SCALE"]);
break;
case "varchar":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = parameters[i];
sqlParameter.Size = (int)dt.Rows[i]["CHARACTER_MAXIMUM_LENGTH"];
sqlParameter.MySqlDbType = MySqlDbType.VarChar;
break;
case "tinyblob":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = (string)parameters[i];
sqlParameter.MySqlDbType = MySqlDbType.TinyBlob;
break;
case "meduimblob":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = (string)parameters[i];
sqlParameter.MySqlDbType = MySqlDbType.MediumBlob;
break;
case "longblob":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = (string)parameters[i];
sqlParameter.MySqlDbType = MySqlDbType.LongBlob;
break;
case "blob":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = (string)parameters[i];
sqlParameter.MySqlDbType = MySqlDbType.Blob;
break;
case "tinytext":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = (string)parameters[i];
sqlParameter.MySqlDbType = MySqlDbType.TinyText;
break;
case "text":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = (string)parameters[i];
sqlParameter.MySqlDbType = MySqlDbType.Text;
break;
case "datetime":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = parameters[i];
sqlParameter.MySqlDbType = MySqlDbType.DateTime;
break;
case "smalldatetime":
if (sqlParameter.Direction == ParameterDirection.Input)
sqlParameter.Value = (DateTime)parameters[i];
sqlParameter.MySqlDbType = MySqlDbType.DateTime;
break;
case "uniqueidentifier":
sqlParameter.MySqlDbType = MySqlDbType.Text;
break;
default: break;
}
#endregion
sqlParameters.Add(sqlParameter);
}
return sqlParameters.ToArray ();
}
/// <summary>
/// 调用存储过程基本方法,返回DataSet结果
/// </summary>
/// <param name="storedProcName">存储过程</param>
/// <param name="parameters">IDataParameter参数</param>
/// <returns></returns>
public DataSet RunProcedure(string storedProcName, IDataParameter[] parameters)
{
using (MySqlConnection connection = new MySqlConnection(this.connectString))
{
connection.Open();
MySqlCommand cmd = new MySqlCommand(storedProcName, connection);
cmd.CommandType = CommandType.StoredProcedure;
if (parameters != null)
{
foreach (MySqlParameter parameter in parameters)
{
if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
(parameter.Value == null))
{
parameter.Value = DBNull.Value;
}
cmd.Parameters.Add(parameter);
}
}
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
{
DataSet ds = new DataSet();
try
{
da.Fill(ds, "ds");
cmd.Parameters.Clear();
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
throw new Exception(ex.Message);
}
return ds;
}
}
}
//调用存储过程返回DataSet结果集:
public Dataset GetResultByProcedure(string ProcedureName, object[] parameters)
{
MySqlParameter[] sqlParameters = GetMySQLParameters(ProcedureName,parameters);
DataSet ds= RunProcedure(ProcedureName, sqlParameters);
return ds;
}
实际使用:
如通过ID获取某城市信息,存储过程为Procedure_GetCityByID,参数为ID,ID=1,则:
Dataset ds=GetResultByProcedure("Procedure_GetCityByID",1)