C# 以适当且简单的方式将数值参数传递给存储过程
我在SQLServer2005中有一个存储过程,它只接受少数类型为BigInt和Number(18,2)的参数 数据库表中有一列ApprovedAmount,类型为:Number(18,2) 从C#(VS-2005)调用此存储过程时,我使用的代码如下:C# 以适当且简单的方式将数值参数传递给存储过程,c#,sql-server-2005,stored-procedures,c#-2.0,C#,Sql Server 2005,Stored Procedures,C# 2.0,我在SQLServer2005中有一个存储过程,它只接受少数类型为BigInt和Number(18,2)的参数 数据库表中有一列ApprovedAmount,类型为:Number(18,2) 从C#(VS-2005)调用此存储过程时,我使用的代码如下: SQLCommand cmd = new SQLCommand(Query, CN) cmd.Parameters.AddWithValue("ApprovedAmount",txtApprovedAmount.Text); 上述参数行给出错
SQLCommand cmd = new SQLCommand(Query, CN)
cmd.Parameters.AddWithValue("ApprovedAmount",txtApprovedAmount.Text);
上述参数行给出错误:无法从字符串转换为数字。
我觉得写上面这行很痛苦,因为要传递的参数太多了:
cmd.Parameters.AddWithValue("ApprovedAmount", Convert.ToDouble(txtApprovedAmount.Text));
是否有任何简单的方法可以传递参数,以便在存储过程本身或使用C#代码中自动将参数转换为适当的数据库表类型
我还想处理一个条件,即如果文本框留空,参数值应作为null传递,我不建议这样做,但我相信您可以让存储过程将varchar作为参数,并在存储过程中将其转换为double。我知道在Oracle中,某些类型可以隐式强制转换,因此如果SQL Server也这样做,您可能可以一起忽略强制转换(取决于您的存储过程所做的)。我不建议这样做,但我相信您可以让存储过程将varchar作为参数,并在存储过程中将其转换为双精度。我知道在Oracle中,某些类型可以隐式强制转换,因此如果SQL Server也这样做,您可能可以一起忽略强制转换(取决于您的存储过程所做的)。类型安全语言的全部要点是,您必须在需要时将一种类型的对象显式强制转换为另一种类型 关于你的最后一点,我想读一下c的条件运算符(?) 它让你做的事情像
(txtApprovedAmount.Text == String.Empty) ? null : txtApprovedAmount.Text;
类型安全语言的全部要点是,必须在需要时将一种类型的对象显式转换为另一种类型 关于你的最后一点,我想读一下c的条件运算符(?) 它让你做的事情像
(txtApprovedAmount.Text == String.Empty) ? null : txtApprovedAmount.Text;
您需要告诉参数它在什么地方是什么类型,您可以编写一个泛型方法,但是您需要为每个调用指定类型,这并不是对现有方法的巨大改进
private static void AddParameter<T>(SqlCommand cmd, string paramName, string value) where T : IConvertible
{
cmd.Parameters.AddWithValue(paramName, Convert.ChangeType(value, typeof(T)));
}
使用这些文本框而不是标准文本框,则添加参数代码变为
cmd.Parameters.AddWithValue("ApprovedAmount", txtApprovedAmount.Value);
实际上,你可以自己动手,用你的类型化控件实现一个ISPParameter接口,这就涵盖了复选框中的布尔值,日期选择器中的日期等等
public interface ISPParameter
{
string Name { get; }
object Value { get; }
}
public class TypedText<T>
: TextBox, ISPParameter
where T : IConvertible
{
private string parameterName;
public TypedText(string parameterName)
{
this.parameterName = parameterName;
}
public object TypedValue
{
get { return Convert.ChangeType(Text, typeof(T)); }
}
string ISPParameter.Name
{
get { return parameterName; }
}
object ISPParameter.Value
{
get { return TypedValue; }
}
}
然后添加参数就变成了
AddParameter(cmd, txtApprovedAmount);
希望这些能为您提供一些想法。您需要告诉参数它是什么类型的,您可以编写一个泛型方法,但您需要为每个调用指定类型,这并不是对现有方法的巨大改进
private static void AddParameter<T>(SqlCommand cmd, string paramName, string value) where T : IConvertible
{
cmd.Parameters.AddWithValue(paramName, Convert.ChangeType(value, typeof(T)));
}
使用这些文本框而不是标准文本框,则添加参数代码变为
cmd.Parameters.AddWithValue("ApprovedAmount", txtApprovedAmount.Value);
实际上,你可以自己动手,用你的类型化控件实现一个ISPParameter接口,这就涵盖了复选框中的布尔值,日期选择器中的日期等等
public interface ISPParameter
{
string Name { get; }
object Value { get; }
}
public class TypedText<T>
: TextBox, ISPParameter
where T : IConvertible
{
private string parameterName;
public TypedText(string parameterName)
{
this.parameterName = parameterName;
}
public object TypedValue
{
get { return Convert.ChangeType(Text, typeof(T)); }
}
string ISPParameter.Name
{
get { return parameterName; }
}
object ISPParameter.Value
{
get { return TypedValue; }
}
}
然后添加参数就变成了
AddParameter(cmd, txtApprovedAmount);
希望这些能为您提供一些解决方法。使用
使用以下命令代替cmd.Parameters.AddWithValue()
您可以对参数进行扩展方法class@peer:在C#2.0:)中不能使用显式定义参数数据类型的重载:
cmd.Parameters.Add(“ApprovedAmount”,SqlDbType.Double)。Value=Convert.ToDouble(txtpapprovedAmount.Text))代码>-如果使用.AddWithVAlue
,则ADO.NET必须根据传入的数据猜测所需的数据类型-因为传入的是字符串,它将使用一个字符串…您可以在参数上创建一个扩展方法class@peer:在C#2.0:)中不能使用显式定义参数数据类型的重载:cmd.Parameters.Add(“ApprovedAmount”,SqlDbType.Double)。Value=Convert.ToDouble(txtpapprovedAmount.Text))代码>-如果您使用.AddWithVAlue
,则ADO.NET必须根据您传入的数据猜测您想要的数据类型-因为您传入一个字符串,它将使用一个字符串…您应该使用System.DBNull.Value而不是null来保持一致性您应该使用System.DBNull.Value而不是null来保持一致性我也这么认为。把越来越多的代码放进数据库本身。我也是这样想的。将越来越多的代码放入数据库本身。后一个看起来很有趣。后一个看起来很有趣。