Параметризация SQL против использования string.format - PullRequest
0 голосов
/ 22 февраля 2019

С точки зрения защиты от внедрения SQL, для простых запросов, является ли одна из следующих стратегий более эффективной, чем другая?:

  1. Использование параметризации:

    using (SqlCommand command = new SqlCommand(@"SELECT * FROM @table", connection))
    {
        command.Parameters.AddWithValue("@table", table_name);
        using (SqlDataReader reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                ...
            }
        }
    }
    
  2. Использование string.Format:

    using (SqlCommand command = new SqlCommand(string.Format(@"SELECT * FROM {0}",table_name), connection))
    using (SqlDataReader reader = command.ExecuteReader())
    {
        while (reader.Read())
        {
            ...
        }
    }
    

Ответы [ 3 ]

0 голосов
/ 22 февраля 2019

Параметризация безопаснее с точки зрения внедрения SQL.Это также лучше для обработки строк и дат.Например, если ваша строка выглядит следующим образом:

"I haven't sleep in two days"

Если вы попытаетесь отформатировать ее в своем запросе, вам придется удвоить символ ', иначе ваш запрос потерпит неудачу.Как если бы вы его параметризовали, SQL сделает это сам.

Единственная причина, по которой я делаю String.Format, - это когда у меня есть, например, список int и я хочу сделать «WHERE COL IN ()»состояние.В этом случае я сделаю String.Format и присоединюсь к List в int, чтобы сгенерировать значения внутри предложения IN.Обратите внимание, что в этом случае у меня есть список int, поэтому здесь нет шансов внедрения SQL.

Я всегда когда-нибудь использую String.Format для динамического SQL, например, для указания имени таблицы, как втвой пример.

0 голосов
/ 22 февраля 2019

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

Параметризация (на мой взгляд) - это всегда путь, поскольку он обеспечивает "«безопасность» вашего запроса (его гораздо сложнее / невозможно ввести в параметризованный запрос), а также позволяет повторно использовать планы запросов, что также может принести большую пользу.

Для того, что у вас есть здесь, однако,Вы не можете параметризовать свой SQL так, как вы ожидаете.Переменная не может заменить имя объекта ( db <> fiddle ).Для этого вам нужен динамический SQL.

Я не собираюсь притворяться, что знаю C #, но я не знаю, что у вас есть, это означало бы, что у вас есть запрос в духе «чего-то», например:

using (SqlCommand command = new SqlCommand(@"DECLARE @SQL nvarchar(MAX) = N'SELECT * FROM ' + QUOTENAME(@table) + N';'; EXEC sp_executesql @SQL;", connection))
{
    command.Parameters.AddWithValue("@table", table_name);

Честно говоря, я понятия не имею, работает ли это в C # таким образом, но именно так вы бы параметризовали динамический объект в (очень) простых терминах.

0 голосов
/ 22 февраля 2019

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

Параметризованные запросы выглядят так, как один

select * from Table t where t.Id = @P1
...