Передача числовых параметров хранимой процедуре соответствующим и простым способом - PullRequest
1 голос
/ 16 сентября 2011

У меня есть хранимая процедура в 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 ]

2 голосов
/ 16 сентября 2011

Я бы не рекомендовал это, но я считаю, что вы можете сделать так, чтобы хранимая процедура принимала varchar в качестве параметра и преобразовывала его в double в хранимой процедуре.Я знаю, что в Oracle некоторые типы могут быть неявно преобразованы, поэтому, если SQL Server делает то же самое, вы можете игнорировать приведение всех вместе (в зависимости от того, что делают ваши хранимые процедуры).

1 голос
/ 16 сентября 2011

Вместо cmd.Parameters.AddWithValue () используйте

cmd.Parameters.Add(new SqlParameter(/*overload that accepts dbType and value*/));
1 голос
/ 16 сентября 2011

Вам нужно указать параметру, какой это тип, где-то, вы могли бы написать универсальный метод, но вам нужно будет указать тип для каждого вызова, это не является значительным улучшением того, что у вас есть

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

Надеюсь, это даст вам несколько идей для работы.

0 голосов
/ 16 сентября 2011

Весь смысл языка, безопасного для типов, заключается в том, что вы должны явным образом приводить объекты одного типа к другому по мере необходимости.

Что касается вашего последнего пункта, я бы прочитал об условном операторе c # (? :) http://msdn.microsoft.com/en-us/library/ty67wk28%28v=vs.80%29.aspx

Что позволяет делать такие вещи, как;

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