以适当且简单的方式将数字参数传递给存储过程

时间:2011-09-16 15:50:37

标签: c# sql-server-2005 stored-procedures c#-2.0

我在SQL Server 2005中有一个存储过程,它接受类型 BigInt Number(18,2)的几个参数。

数据库表中有一列ApprovedAmount,类型为:Number(18,2)。

从C#(VS-2005)调用此存储过程时,我使用的代码如下:

SQLCommand cmd = new SQLCommand(Query, CN)

cmd.Parameters.AddWithValue("ApprovedAmount",txtApprovedAmount.Text);

上述参数行给出错误:无法从字符串转换为数字..

我觉得写下面的行如下所示是很痛苦的,因为要传递的参数太多了:

cmd.Parameters.AddWithValue("ApprovedAmount", Convert.ToDouble(txtApprovedAmount.Text));

是否有任何简单的方法来传递参数,以便它们在存储过程本身或使用C#代码自动转换为适当的数据库表类型?

我还想处理一个条件,即如果TextBox留空,则参数值应该作为 null 传递。

4 个答案:

答案 0 :(得分:2)

我不推荐它,但我相信您可以让存储过程将varchar作为参数,并将其转换为存储过程中的double。我知道在Oracle中可以隐式转换某些类型,因此如果SQL Server执行相同的操作,您可能会忽略所有类型的转换(取决于您的存储过程执行的操作)。

答案 1 :(得分:1)

你需要告诉参数它在哪个类型,你可以写一个通用的方法,但是你需要为每个调用指定类型,这不是对你所拥有的东西的巨大改进

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)); }
    }
}

使用这些代替标准TextBox,然后添加参数代码变为

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);

希望这些能为您提供一些想法。

答案 2 :(得分:1)

使用

代替cmd.Parameters.AddWithValue()
cmd.Parameters.Add(new SqlParameter(/*overload that accepts dbType and value*/));

答案 3 :(得分:0)

类型安全语言的全部意义在于您必须将一种类型的对象明确地转换为另一种类型的对象作为&amp;需要时。

关于你的最后一点,我会读到c#的条件运算符(?:) http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.80%29.aspx

让你做的事情可以做到;

(txtApprovedAmount.Text == String.Empty) ? null : txtApprovedAmount.Text;