2017-02-09 6 views
-1

В моем коде я всегда получаю значение 'user_id' как -1. что что-то неправильное в запросе ???SQL Query всегда возвращает -1 как результат в C# asp.net

, и я также хочу, чтобы запрос соединения для этого.

  using (SqlConnection con = new SqlConnection(connectionString)) 
      { 
       try 
       { 
        SqlCommand cmd; 
        if (con.State == ConnectionState.Closed) 
        { 
         con.Open(); 
        } 
        var user = Page.User.Identity.Name; 
        cmd = new SqlCommand("select UserId from Users where UserName='"+user+"'", con); 
        var user_id=cmd.ExecuteNonQuery(); 
        cmd = new SqlCommand("select Gender from UserDetails where userId='"+user_id+"'"); 
        var gender = cmd.ExecuteNonQuery(); 
        SqlDataReader rdr = cmd.ExecuteReader(); 
        if (rdr.Read()) 
        { 

        } 
       } 
       catch (Exception e) { } 
      } 
+2

Попробуйте выполнить cmd.ExecuteScalar и добавьте его в int или задолго до назначения var. –

+1

Вы должны использовать 'ExecuteNonQuery', если вы не ожидаете результата. В этом случае вы, скорее всего, захотите «ExecuteScalar». - http://stackoverflow.com/questions/2974154/what-is-the-difference-between-executescalar-executereader-and-executenonquery – smoksnes

+1

[Возвращаемое значение Тип: System.Int32 Число затронутых строк.] (https : //msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery (v = vs.110) .aspx) – rene

ответ

3

Во-первых, ExecuteNonQuery не возвращает никаких результатов. Если вы хотите вернуть одно значение, используйте ExecuteScalar.

Во-вторых, путем конкатенации строк для создания SQL-запроса вы уязвимы для SQL-инъекций и ошибок преобразования. Google для «Bobby Tables». Или представьте, что произойдет, если кто-то введет '; DELETE FROM Users;-- в качестве имени пользователя.

В-третьих, если вы хотите получить данные пользователя, не выполнить два отдельных запроса. Используйте JOIN, например:

var query = "Select Gender from UserDetails d " + 
      " inner Join Users on Users.UserId=d.UserID " + 
      " where [email protected]"; 

var genderCmd=new SqlCommand(query); 
genderCmd.Parameters.Add("@user",SqlDbType.NVarChar,30); 

using (SqlConnection con = new SqlConnection(connectionString)) 
{ 
    con.Open(); 

    genderCmd.Connection=con; 
    genderCmd.Parameters["@user].Value=user; 
    var gender=(string)genderCmd.ExecuteScalar(); 
    return gender; 
} 

Вы можете сохранить запрос и команды в полях и использовать их по мере необходимости, например:

void InitializeCommands() 
{ 
    var query = "Select Gender from UserDetails d " + 
       " inner Join Users on Users.UserId=d.UserID " + 
       " where [email protected]"; 

    _genderCmd=new SqlCommand(query); 
    _genderCmd.Parameters.Add("@user",SqlDbType.NVarChar,30); 

} 

//.... 

public string GetGender(string user) 
{ 
    using (SqlConnection con = new SqlConnection(connectionString)) 
    { 
     con.Open(); 

     genderCmd.Connection=con; 
     genderCmd.Parameters["@user"].Value=user; 
     var gender=(string)genderCmd.ExecuteScalar(); 
     return gender; 
    } 
} 

Вы можете использовать асинхронные версии Open, ExecuteScalar, чтобы избежать блокировки поток во время ожидания ответа сервера, например:

public Task<string> GetGender(string user) 
{ 
    using (SqlConnection con = new SqlConnection(connectionString)) 
    { 
     await con.OpenAsync(); 

     genderCmd.Connection=con; 
     genderCmd.Parameters["@user"].Value=user; 
     var gender=await genderCmd.ExecuteScalarAsync(); 
     return (string)gender; 
    } 
} 

IO операция, таких как звонки в базу данных обрабатываются с использованием портов завершения ввода-вывода на уровне сетевой подсистемы, а не нитки.

+0

да, спасибо, сэр за полезную информацию, за ее работу, и я многому научился от этого – user7415073

0

ExecuteNonQuery ничего, кроме числа пострадавших записей для вставки, удаления или обновления не возвращаются. Он возвращает -1 для всех других типов запросов.

Что вы хотите, это ExecuteScalar. Обратите внимание, что результатом запроса может быть также NULL (DBNull.Value).

3

Вы должны использовать ExecuteScalar вместо ExecuteNotQuery.

ExecuteNonQuery:

  1. Он не возвращает никаких данных.
  2. Используется со вставкой и обновлением.
  3. Он возвращает только количество затронутых строк.

ExecuteScalar:

  1. возвращает только одно значение.
  2. Это значение будет первым значением первой строки столбца.

ExecuteReader

  1. Сво для командных объектов.
  2. Он возвращает значение, заданное базой данных посредством оператора select.
+0

Good Объяснение. – UJS

+0

good e xplanation – user7415073

0

AS MSDN говорит, ExecuteNonQuery возвращает:

Для UPDATE, INSERT и DELETE заявления, возвращаемое значение является число строк, затронутых командой. Когда триггер существует в вставленной или обновляемой таблице , возвращаемое значение включает в себя номер строк, затронутых операциями вставки или обновления, и числом строк, затронутых триггером или триггерами. Для всех остальных типов операторов возвращаемое значение равно -1. Если происходит откат, значение возврата равно -1.

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

cmd = new SqlCommand("select UserId from Users where UserName= @user, con); 
cmd.Parameters.AddWithValue("@user", user); 
int user_id = Convert.ToInt32(cmd.ExecuteScalar()); //NOTE THAT YOU WILL ALWAYS HAVE TO CAST THE RESULT, AS IT RETURNS Object 
+0

Обратите также внимание на то, что вы всегда должны проверять результат для 'null' /' DBNull.Value' перед тем, как сделать. –

+0

Bobby столы. Конкатенация строк. SQL Injection. NO. Предположим, что люди будут копировать ответ так, как есть. Создайте правильно параметризованный запрос, например '' SELECT ... UserName = @ user ', con); cmd.Parameters.AddWithValue ("@ user", user); "'. Это только одна строка –

+0

@PanagiotisKanavos справа. отредактировал – NicoRiff