[原创]c#调用存储过程 不声明参数拿来即用的办法2种
2023-04-05 本文已影响0人
吉凶以情迁
这个东西就是靠思考了,如果不去想就自然以为没这个东西.懒癌发作
第一种使用
SqlCommand cmd = new SqlCommand(procName, sqlConnection);
cmd.CommandType = CommandType.StoredProcedure;
SqlCommandBuilder.DeriveParameters(cmd);
第二种
SqlCommand command = new SqlCommand();
SqlCommand returnCommand = new SqlCommand();
returnCommand.CommandType = CommandType.StoredProcedure;
returnCommand.CommandText = storedProcedureName;
using (SqlConnection connection = new SqlConnection(SercretCS.Conn))
{
connection.Open();
command.CommandText = "SELECT PARAMETER_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE,PARAMETER_MODE FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_NAME = '" + storedProcedureName + "' ORDER BY ORDINAL_POSITION";
command.Connection = connection;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = reader["PARAMETER_NAME"].ToString();
parameter.SqlDbType = (SqlDbType)Enum.Parse(typeof(SqlDbType), reader["DATA_TYPE"].ToString(), true);
if (reader["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value)
{
parameter.Size = Convert.ToInt32(reader["CHARACTER_MAXIMUM_LENGTH"]);
}
if (reader["NUMERIC_PRECISION"] != DBNull.Value)
{
parameter.Precision = byte.Parse(reader["NUMERIC_PRECISION"].ToString());
}
if (reader["NUMERIC_SCALE"] != DBNull.Value)
{
parameter.Scale = byte.Parse(reader["NUMERIC_SCALE"].ToString());
}
//parameter.Value = default(parameter.SqlDbType);
String direction = reader["PARAMETER_MODE"].ToString();
if (direction == "IN")
{
parameter.Direction = ParameterDirection.Input;
}
else if (direction == "OUT")
{
parameter.Direction = ParameterDirection.Output;
}
else if (direction == "INOUT")
{
parameter.Direction = ParameterDirection.InputOutput;
}
else if (direction == "RETURN_VALUE")
{
parameter.Direction = ParameterDirection.ReturnValue;
}
if (parameter.Direction == ParameterDirection.Input || parameter.Direction == ParameterDirection.InputOutput)
{
// 设置默认值
SetDefaultValueBySqlParameterType(parameter);
}
returnCommand.Parameters.Add(parameter);
}
reader.Close();
}
说明
上面两种方法都有缺陷,都会提示参数没传递,
所以设置之后还缺一个东西,就是初始化参数默认值
如下输入参数的默认值代码
public static void SetDefaultValueBySqlParameterType(SqlParameter parameter)
{
if (parameter.Direction == ParameterDirection.Input || parameter.Direction == ParameterDirection.InputOutput)
{
// 设置默认值
switch (parameter.SqlDbType)
{
case SqlDbType.Bit:
parameter.Value = false;
break;
case SqlDbType.TinyInt:
case SqlDbType.SmallInt:
case SqlDbType.Int:
case SqlDbType.BigInt:
case SqlDbType.Float:
case SqlDbType.Real:
case SqlDbType.Decimal:
case SqlDbType.Money:
case SqlDbType.SmallMoney:
parameter.Value = 0;
break;
case SqlDbType.NVarChar:
case SqlDbType.VarChar:
case SqlDbType.NChar:
case SqlDbType.Char:
case SqlDbType.Text:
case SqlDbType.NText:
parameter.Value = string.Empty;
break;
case SqlDbType.UniqueIdentifier:
parameter.Value = Guid.Empty;
break;
case SqlDbType.DateTime:
case SqlDbType.SmallDateTime:
parameter.Value = DateTime.MinValue;
break;
case SqlDbType.Binary:
case SqlDbType.VarBinary:
case SqlDbType.Image:
parameter.Value = new byte[0];
break;
case SqlDbType.Xml:
parameter.Value = new XmlDocument();
break;
default:
parameter.Value = DBNull.Value;
break;
}
}
}
之后就可以正常用了.
最后我实现了只需要输入网址改下参数名=xx,xx,xx就能随意调用测试存储过程
第一种原理应该就是类似第二种,如果没有设置sqlconnect的情况下直接执行那句话,那就回提示连接问题.
如果通过下标访问,第一种应该+1,因为他的第一个参数是{@RETURN_VALUE}
是他自己加进去的