Проблема с использованием моей хранимой процедуры - PullRequest
1 голос
/ 31 августа 2009

У меня есть следующий метод, который должен быть общим методом «Сохранить в SQL» для моего приложения.

protected void EjecutarGuardar(string ProcedimientoAlmacenado, object[] Parametros)
        {
            SqlConnection Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);

            SqlCommand Command = Connection.CreateCommand();             
            Command.CommandType = CommandType.StoredProcedure;
            foreach (object X in Parametros)
            {
                Command.Parameters.Add(X);
            }            

            Connection.Open();
            Command.ExecuteNonQuery();
            Connection.Close();

            Connection.Dispose();
        }

Мне нужно передать ИМЯ StoredProcedure и массив, заполненный параметрами. Я немного растерялся на этом этапе. Где мне следует использовать НАИМЕНОВАНИЕ хранимой процедуры "ProgramsimientoAlmacenado"?

Я думаю, может быть, Command.Command? Но я там потерян. Любая помощь?

Edit: для простоты скажем, у меня есть хранимая процедура под названием "ABC" в моей базе данных. Как я могу связать его с моей «Командой» SqlCommand в моем коде?

Ответы [ 4 ]

3 голосов
/ 31 августа 2009

Command.CommandText= ProcedimientoAlmacenado

Параметры также должны иметь имена. Содержит ли массив Parametros объекты SqlParameter или общие объекты C #?

Если параметры являются общими объектами C #, лучше передать в словарь имен и значений:

protected void EjecutarGuardar(string ProcedimientoAlmacenado, 
    Dictionary<string, object> Parametros)
{
    using (SqlConnection Connection = new SqlConnection(...))
    {
        Connection.Open();
        SqlCommand Command = Connection.CreateCommand()
        Command.CommandText = ProcedimientoAlmacenado;
        Command.Connection = Connection;       
        Command.CommandType = CommandType.StoredProcedure;
        foreach (string name in Parametros.Keys)
        {
          Command.Parameters.AddWithValue(name, Parametros[name] ?? DBNull.Value);
        }            
        Command.ExecuteNonQuery();
    }
}

Это быстрый и грязный подход. Обратите внимание, что при таком подходе обычно возникают проблемы, потому что AddWithValue будет передавать параметр типа NVARCHAR для строки, а не VARCHAR, а в случае специального SQL это может вызвать проблемы с индексной SARG-способностью для столбцов VARCHAR (поскольку преобразование будет всегда из VARCHAR в NVARCHAR, а не наоборот). Однако с хранимыми процедурами нет такой проблемы, потому что процедуры имеют параметры типов, и, следовательно, принудительное принуждение происходит с VARCHAR, если процедура была создана с параметром типа VARCHAR.

У вас также будут проблемы с передачей NULL-параметров, поэтому вам нужно сделать что-то вроде, параметр должен быть DBNull.Value, а не null:

Command.Parameters.AddWithValue(name, Parametros[name] ?? DBNull.Value);

В высокопроизводительных системах этот подход также излишне загрязняет кэш выполнения, потому что AddWithValue будет передавать параметры типа NVARCHAR(<exact length of the string>), а не NVARCHAR(<length of the database type>). Таким образом, Paramaters.AddWithValue("@name", "John") и Parameters.AddwithValue("@name", "Doe") создадут два отдельных плана в кэше, потому что один вызывается с параметром типа NVARCHAR (4), другой - с параметром NVARCHAR (3), и они рассматриваются в кэше плана SQL как разных типов . Это не проблема для простых проектов, но для более сложных и высокопроизводительных проектов рекомендуется явно задавать типы параметров.

Я бы порекомендовал избегать такого рода универсальных процедур «один размер подходит всем» и вместо этого написать слой доступа к данным с явной оболочкой C # для каждой процедуры базы данных с соответствующими типами параметров. Строго типизированный набор данных может на самом деле сделать это, другой альтернативой (мой любимый и то, что я всегда использую) является генерация всего убийцы доступа к данным из файла XML с использованием таблицы стилей XSLT, которая создает оболочки C #. Разумеется, исходный XML извлекается из метаданных базы данных.

0 голосов
/ 31 августа 2009

Установите для свойства CommandText объекта SqlCommand имя вашей хранимой процедуры:

Command.CommandText = "MyStoredProcedureName";
0 голосов
/ 31 августа 2009

Command.CommandText = "ProcedimientoAlmacenado"; До или после Command.CommandType = CommandType.StoredProcedure; Это не обязательно, но я так и делаю.

0 голосов
/ 31 августа 2009
Command.ComandText = "storedProcName";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...