За и против использования SqlCommand Готовятся в C#?

Когда я читал книги для изучения, C# (могли бы быть некоторые старые Visual Studio 2005 книги) я встретился с советом всегда использовать SqlCommand.Prepare каждый раз я выполняю вызов SQL (ли a it SELECT/UPDATE или INSERT на SQL-СЕРВЕРЕ 2005/2008), и я передаю параметры ему. Но это действительно так?

  1. Это должно быть сделано каждый раз? Или просто иногда?

  2. Имеет значение, является ли это одним параметром, передаваемым или пять или двадцать?

  3. Какое повышение это должно дать если таковые имеются? Это было бы примечательно вообще (я использовал SqlCommand.Prepare здесь и пропущенный это там и никогда не имело проблем или заметных различий).

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

public static decimal pobierzBenchmarkKolejny(string varPortfelID, DateTime data, decimal varBenchmarkPoprzedni, decimal varStopaOdniesienia) {
    const string preparedCommand = @"SELECT [dbo].[ufn_BenchmarkKolejny](@varPortfelID, @data, @varBenchmarkPoprzedni,  @varStopaOdniesienia) AS 'Benchmark'";
    using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP)) //if (varConnection != null) {
    using (var sqlQuery = new SqlCommand(preparedCommand, varConnection)) {
        sqlQuery.Prepare();
        sqlQuery.Parameters.AddWithValue("@varPortfelID", varPortfelID);
        sqlQuery.Parameters.AddWithValue("@varStopaOdniesienia", varStopaOdniesienia);
        sqlQuery.Parameters.AddWithValue("@data", data);
        sqlQuery.Parameters.AddWithValue("@varBenchmarkPoprzedni", varBenchmarkPoprzedni);
        using (var sqlQueryResult = sqlQuery.ExecuteReader())
            if (sqlQueryResult != null) {
                while (sqlQueryResult.Read()) {

                }
            }
    }
}

Дополнительное разъяснение:

Если я перемещаюсь sqlQuery.Prepare() как в коде ниже исключения брошен, что размер должен быть явно объявлен, который в основном приводит меня к размышлению этого наличие sqlQuery.Prepare() как сначала делает это бесполезным? Кто-то может показать надлежащее использование с помощью моего примера?

public static decimal pobierzBenchmarkKolejny(string varPortfelID, DateTime data, decimal varBenchmarkPoprzedni, decimal varStopaOdniesienia) {
    const string preparedCommand = @"SELECT [dbo].[ufn_BenchmarkKolejny](@varPortfelID, @data, @varBenchmarkPoprzedni,  @varStopaOdniesienia) AS 'Benchmark'";
    using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP)) //if (varConnection != null) {
    using (var sqlQuery = new SqlCommand(preparedCommand, varConnection)) {

        sqlQuery.Parameters.AddWithValue("@varPortfelID", varPortfelID);
        sqlQuery.Parameters.AddWithValue("@varStopaOdniesienia", varStopaOdniesienia);
        sqlQuery.Parameters.AddWithValue("@data", data);
        sqlQuery.Parameters.AddWithValue("@varBenchmarkPoprzedni", varBenchmarkPoprzedni);
        sqlQuery.Prepare();
        using (var sqlQueryResult = sqlQuery.ExecuteReader())
            if (sqlQueryResult != null) {
                while (sqlQueryResult.Read()) {

                }
            }
    }
}

Как я сделал бы это? Путем добавления .size рядом с параметрами и выполнения varPortfel. Lenght, если это - строка и т.д.?

35
задан MadBoy 22 March 2010 в 21:45
поделиться

2 ответа

Из документации MSDN:

"Прежде чем вызвать Prepare, укажите тип данных каждого параметра в оператора, который будет подготовлен. Для каждого параметра, имеющего переменную длину типа данных, вы должны установить свойство Size максимальный размер. Prepare возвращает ошибку, если условия не выполняются.

Если вы вызываете метод Execute после вызова Prepare, любое значение параметра которое больше, чем значение указанное свойством Size, автоматически автоматически усекается до исходного заданного размера параметра, и никакие ошибки усечения не возвращаются.

Выходные параметры (как подготовленные, так и не подготовленные или нет) должны иметь указанный пользователем тип данных. Если указан тип данных переменной длины тип данных, вы также должны указать максимальный размер."

Кроме того, "Если свойство CommandType установлено значение TableDirect, Prepare ничего не делает. Если CommandType установлен в StoredProcedure, вызов функции Prepare должен быть успешным, ..."

В общем, это используется для того, чтобы убедиться, что конечный пользователь не использует технику SQL Injection для добавления или удаления информации из базы данных.

Я изучил этот вопрос и посмотрел эту статью http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.prepare.aspx. Ваша проблема в том, что вам нужно определить параметры до запуска .Prepare(), а затем установить параметры после запуска .Prepare(). Сейчас вы делаете и то, и другое до. Я бы попробовал сделать что-то вроде этого (обратите внимание, я не тестировал это, поэтому мой синтаксис может быть немного неправильным).

public static decimal pobierzBenchmarkKolejny(string varPortfelID, DateTime data, decimal varBenchmarkPoprzedni, decimal varStopaOdniesienia) {
    const string preparedCommand = @"SELECT [dbo].[ufn_BenchmarkKolejny](@varPortfelID, @data, @varBenchmarkPoprzedni,  @varStopaOdniesienia) AS 'Benchmark'";
    using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetailsDZP)) //if (varConnection != null) {
    using (var sqlQuery = new SqlCommand(preparedCommand, varConnection)) {

        sqlQuery.Parameters.Add("@varPortfelID");
        sqlQuery.Parameters.Add("@varStopaOdniesienia");
        sqlQuery.Parameters.Add("@data");
        sqlQuery.Parameters.Add("@varBenchmarkPoprzedni");

        sqlQuery.Prepare();
        sqlQuery.ExecuteNonQuery();//This might need to be ExecuteReader()

        sqlQuery.Parameters[0].Value = varPortfelID;
        sqlQuery.Parameters[1].Value = varStopaOdniesienia;
        sqlQuery.Parameters[2].Value = data;
        sqlQuery.Parameters[3].Value = varBenchmarkPoprzedni;

        using (var sqlQueryResult = sqlQuery.ExecuteReader())
            if (sqlQueryResult != null) {
                while (sqlQueryResult.Read()) {

                }
            }
    }
}
12
ответ дан 27 November 2019 в 15:47
поделиться

Другое преимущество состоит в том, что при этом план запроса SQL компилируется, кэшируется и повторно используется . Это не имеет большого значения, если количество обращений к вашему запросу невелико, но если у вас их много, это действительно дает некоторые значительные преимущества в производительности.

6
ответ дан 27 November 2019 в 15:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: