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

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); 上述参数行给出错

我在SQLServer2005中有一个存储过程,它只接受少数类型为BigIntNumber(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#代码中自动将参数转换为适当的数据库表类型


我还想处理一个条件,即如果文本框留空,参数值应作为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来保持一致性我也这么认为。把越来越多的代码放进数据库本身。我也是这样想的。将越来越多的代码放入数据库本身。后一个看起来很有趣。后一个看起来很有趣。