由於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)