Reputation: 14161
I have a stored procedure in SQL Server 2005 which accepts few parameters of type BigInt and Number(18,2).
There is a column ApprovedAmount in the database table of type: Number(18,2).
While calling this stored procedure from C# (VS-2005), I am using code like:
SQLCommand cmd = new SQLCommand(Query, CN)
cmd.Parameters.AddWithValue("ApprovedAmount",txtApprovedAmount.Text);
The above parameter line gives error: Cannot convert from String to Numeric..
I find it painful to write the above line as below because there are so many parameters to pass:
cmd.Parameters.AddWithValue("ApprovedAmount", Convert.ToDouble(txtApprovedAmount.Text));
Is there any easy way to pass parameters so that they are automatically converted to the appropriate database table type in either Stored Procedure itself or with C# code?
I also want to handle a condition that if the TextBox was left blank, the parameter value should be passed as null.
Upvotes: 1
Views: 3809
Reputation: 51711
You need to tell the parameter what type it is somewhere, you could write a generic method, but you'll need to specify the type for each call, it's not a huge improvement on what you have
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);
Alternatively, you could subclass TextBox so it has a type, or create new user controls with a Type
property e.g. Subclassed
public class TypedText<T>
: TextBox
where T : IConvertible
{
public object Value
{
get { return Convert.ChangeType(Text, typeof(T)); }
}
}
Use these instead of standard TextBoxes, then your add parameter code becomes
cmd.Parameters.AddWithValue("ApprovedAmount", txtApprovedAmount.Value);
Actually, you could knock yourself out and have an ISPParameter interface that your typed controls implement, this then covers you for booleans from check boxes, dates from datepickers etc.
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; }
}
}
with an AddParameter method
public void AddParam(SqlCommand cmd, ISPParameter param)
{
cmd.Parameters.AddWithValue(param.Name, param.Value);
}
Then adding parameters becomes
AddParameter(cmd, txtApprovedAmount);
Hope these give you a few ideas to work on.
Upvotes: 1
Reputation: 26
Instead of cmd.Parameters.AddWithValue(), use
cmd.Parameters.Add(new SqlParameter(/*overload that accepts dbType and value*/));
Upvotes: 1
Reputation: 4179
The whole point of a type-safe language is that you must explicitly cast objects of one type to another as & when required.
With regard to your last point I would read up on c#'s conditional operator (?:) http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.80%29.aspx
Which lets you do things like;
(txtApprovedAmount.Text == String.Empty) ? null : txtApprovedAmount.Text;
Upvotes: 0
Reputation: 961
I wouldn't recommend it, but I believe that you can have the stored procedure take varchar as a parameter, and convert it to a double in the stored procedure. I know in Oracle some types can be implicitly cast, so if SQL Server does the same, you might be able to ignore casting all together (depending on what your stored procedures do).
Upvotes: 2