我在SQL Server 2005中有一个存储过程,它接受类型BigInt和Number(18,2)的几个参数。
数据库表中存在一个类型为:Number(18,2)的列ApprovedAmount。
当从c# (VS-2005)调用这个存储过程时,我使用如下代码:SQLCommand cmd = new SQLCommand(Query, CN)
cmd.Parameters.AddWithValue("ApprovedAmount",txtApprovedAmount.Text);
上面的参数行给出错误:Cannot convert from String to Numeric..
我发现像下面这样写上面的行是很痛苦的,因为要传递的参数太多了:
cmd.Parameters.AddWithValue("ApprovedAmount", Convert.ToDouble(txtApprovedAmount.Text));
是否有任何简单的方法来传递参数,以便它们在存储过程本身或c#代码中自动转换为适当的数据库表类型?我还想处理一个条件,如果TextBox是空的,参数值应该传递为null
我不推荐这样做,但是我相信您可以让存储过程将varchar作为参数,并在存储过程中将其转换为double类型。我知道在Oracle中有些类型可以隐式强制转换,所以如果SQL Server也这样做,你可能可以忽略所有的强制转换(取决于你的存储过程做什么)。
使用
代替cmd.Parameters.AddWithValue()cmd.Parameters.Add(new SqlParameter(/*overload that accepts dbType and value*/));
你需要在某处告诉参数它是什么类型,你可以写一个泛型方法,但你需要为每次调用指定类型,这对你所拥有的并没有很大的改进
private static void AddParameter<T>(SqlCommand cmd, string paramName, string value) where T : IConvertible
{
cmd.Parameters.AddWithValue(paramName, Convert.ChangeType(value, typeof(T)));
}
…
AddParameter<double>(cmd, "ApprovedAmount", txtApprovedAmount.Text);
或者,你可以子类化TextBox,使它有一个类型,或创建新的用户控件与Type
属性,例如:子类化
public class TypedText<T>
: TextBox
where T : IConvertible
{
public object Value
{
get { return Convert.ChangeType(Text, typeof(T)); }
}
}
使用这些而不是标准的TextBoxes,那么你的add参数代码将变成
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方法
public void AddParam(SqlCommand cmd, ISPParameter param)
{
cmd.Parameters.AddWithValue(param.Name, param.Value);
}
则添加参数变为
AddParameter(cmd, txtApprovedAmount);
类型安全语言的重点在于必须显式地将一种类型的对象转换为另一种类型,如&当必需的。
关于你的最后一点,我会阅读c#的条件运算符(?:)http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.80%29.aspx
可以让你做像;
(txtApprovedAmount.Text == String.Empty) ? null : txtApprovedAmount.Text;