2016-11-30 2 views
-2

C#, RazorОшибка с SqlDataReader

мой код:

@using (SqlConnection Praktikum2 = new SqlConnection("Data Source=Mark\\SQLEXPRESS;Initial Catalog=Connection;Integrated Security=True")) 
{ 

using(connection) 
{ 
    SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name = " + Request.Params["kategory"]); 

    connection.Open(); 
    SqlDataReader reader = command.ExecuteReader(); //ERROR!!! 
    while (reader.Read()) 
    { 
     string ID = reader["KategorieID"].ToString() ; 

     Console.WriteLine("ID = {0}", ID); 
    } 
    reader.Close(); 
}; 
} 

я получаю сообщение об ошибке, что есть неправильный синтаксис около "=".

как я могу это решить?

+3

Используйте параметры вместо конкатенации и ваша проблема исчезает – Steve

+3

Вы определенно должны использовать SQL параметры для команды. Использование этого метода будет медленнее, а также оставить вас открытым для SQL-инъекции. – CF5

ответ

1

Если столбец kategory не типа данных целого числа, то вам необходимо окружить значение с ('), т.е. одиночными кавычками

Тогда ваш запрос будет как

SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name ='" + Request.Params["kategory"] + "'"); 
1

Вы забыли назначить connection - command. Поэтому, когда вы звоните ExecuteReader(), он не знает, по какому соединению он должен быть выполнен.

Вы можете назначить соединение, как это:

SqlCommand command = new SqlCommand(
      "SELECT KategoryID FROM Kategory WHERE Name = " + Request.Params["kategory"], 
      connection); // provide connection as second parameter! 

или использовать connection.CreateCommand() создать команду.

Во-вторых, вы забыли кавычки вокруг вашей строки:

 "SELECT KategoryID FROM Kategory WHERE Name = '" + Request.Params["kategory"] + "'" 

но вставки пользовательских данных непосредственно в запросе открывает свой код SQL Injection. Вместо этого используйте параметризованные запросы.

+0

@Jamiec right, пропустил это описание ошибки. Очевидно, что 'ExecuteReader' сначала анализирует SQL, а затем проверяет соединение. Поэтому после фиксации кавычек/параметризации отсутствующего соединения была бы следующая ошибка. –

1

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

Единственный способ справиться с этим, чтобы использовать параметр запроса

SqlCommand command = new SqlCommand(@"SELECT KategoryID FROM Kategory 
             WHERE Name = @name", connection); 
command.Parameters.Add("@name", SqlDbType.NVarChar).Value = Request.Params["kategory"]; 

Кроме того, как отмечалось в другом ответе, ваш код, кажется, не ассоциировали соединение с командой, я думаю, что это просто опечатка здесь, потому что сообщение об ошибке в этом случае было бы «нужно открытое соединение»

+0

Параметр имеет тип. Клиент Sql Server определяет различные типы. NVarChar означает, что вы передаете значение, которое хранится в столбце типа NVarChar в вашей таблице базы данных. Это устраняет любую двусмысленность между кодом NET и движком базы данных. – Steve

+0

Эти типы определены путем перечисления [SqlDbType] (https://msdn.microsoft.com/en-us/library/system.data.sqldbtype (v = vs.110) .aspx). Конечно, вы можете настроить тип в соответствии с фактическим типом базы данных вашего столбца. – Steve

+0

У вас есть _using System.Data; _ в начале вашего исходного кода? – Steve

1

Исключение вызвано тем, как вы создаете свой SQL-оператор. Исправление не должно корректировать синтаксис, но вместо этого использовать параметры. Это предотвратит атаки SQL-инъекций.

Также

  1. Вы действительно не должны быть сочинительство SQL в ваших взглядах, сделайте это в методе контроллера вместо этого и возвращать результат в модели, которые будут использоваться в вашем представлении. Еще лучше отвлеките его на другой слой и вызовите этот слой с вашего контроллера. Это связано с SoS (Разделение проблем), ваш код будет очень сложно поддерживать, если вы просто напишете все в своих представлениях.
  2. Заверните свои соединения, команды и считыватели в блоках using.

Модифицированный код

@{ 
    using(SqlConnection Praktikum2 = new SqlConnection("Data Source=Mark\\SQLEXPRESS;Initial Catalog=Connection;Integrated Security=True")) 
    using(SqlCommand command = new SqlCommand("SELECT KategoryID FROM Kategory WHERE Name = @name", Praktikum2)) 
    { 
     command.Parameters.Add(new SqlParameter("@name", SqlDbType.VarChar){ Value = Request.Params["kategory"]}); 
     connection.Open(); 
     using(SqlDataReader reader = command.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       string ID = reader["KategorieID"].ToString() ; 
       Console.WriteLine("ID = {0}", ID); 
      } 
     } 
    } 
} 
Смежные вопросы