2014-01-27 5 views
1

Я пытаюсь получить последний идентификатор, вставленный с помощью SCOPE_IDENTITY, но у меня есть ошибка. Я использую SQL Server 2012 с Visual Studio Express 2013Извлечение последнего вставленного идентификатора с помощью scope_Identity()

Вот мой код

protected void PerformInscription(string sEmail, string sPassword,string sName) 
{ 
    bool buserIdAuthenticated = false; 
    string salt = null; 
    string passwordHash = pwdManager.GeneratePasswordHash(txtPassword.Text, out salt); 

    SqlConnection sqlConnection; 
    sqlConnection = new SqlConnection(); 

    try 
    { 
     sqlConnection.ConnectionString = sqlDataSource1.ConnectionString; 

     string insertStatement = "INSERT INTO [User] " 
           + "(email, hash, salt, name) " 
           + "VALUES (@email, @hash, @salt, @name);" 
           + "SELECT SCOPE_IDENTITY() AS id_user;"; 

     SqlCommand insertCommand = new SqlCommand(insertStatement, sqlConnection); 

     insertCommand.Parameters.Add("@email", SqlDbType.VarChar, 50).Value = sEmail; 
     insertCommand.Parameters.Add("@hash", SqlDbType.VarChar, 50).Value = passwordHash; 
     insertCommand.Parameters.Add("@salt", SqlDbType.VarChar, 50).Value = salt; 
     insertCommand.Parameters.Add("@nom", SqlDbType.VarChar, 50).Value = sName; 

     sqlConnection.Open(); 

     int count = insertCommand.ExecuteNonQuery(); 

     int User_ID = Convert.ToInt32(insertCommand.Parameters["@id_user"].Value); 
     Session["Id_user"] = User_ID; 

     insertCommand.Dispose(); 

     if (count >= 1) 
     { 
      buserIdAuthenticated = true;      
      Session["userIdAuthenticated"] = buserIdAuthenticated; 
      Response.Redirect("../pages/Welcome.aspx"); 
     } 
    } 

    catch (SqlException ex) 
    { 
     lblMessage.Text = ex.Message; 
    } 

    finally 
    { 
     sqlConnection.Close(); 
    } 
    } 
} 

Я хочу, чтобы поймать последний user_id который был определить, как Идентичность для автоматического увеличения.

Здесь ошибка я получил

Исключение типа «System.IndexOutOfRangeException» произошло в System.Data.dll, но не был обработан в пользовательском коде.

Дополнительная информация: SqlParameter с параметромName '@id_user' не содержится в этом SqlParameterCollection.

Я решил разделить два запроса. 1 вставка и 1 выберите

SqlConnection sqlConnection; 
    sqlConnection = new SqlConnection(); 

    try 
    { 
     sqlConnection.ConnectionString = sqlDataSource1.ConnectionString; 

     string insertStatement = "INSERT INTO [User] " 
           + "(email, hash, salt, name) " 
           + "VALUES (@email, @hash, @salt, @name)"; 

     SqlCommand insertCommand = new SqlCommand(insertStatement, sqlConnection); 

     insertCommand.Parameters.Add("@email", SqlDbType.VarChar, 50).Value = sEmail; 
     insertCommand.Parameters.Add("@hash", SqlDbType.VarChar, 50).Value = passwordHash; 
     insertCommand.Parameters.Add("@salt", SqlDbType.VarChar, 50).Value = salt; 
     insertCommand.Parameters.Add("@name", SqlDbType.VarChar, 50).Value = sName; 

     sqlConnection.Open(); 

     int count = insertCommand.ExecuteNonQuery(); 

     insertCommand.Dispose(); 

     if (count >= 1) 
     { 
      string selectStatement = "SELECT SCOPE_IDENTITY() AS id_user"; 
      SqlCommand selectCommand = new SqlCommand(selectStatement, sqlConnection); 
      selectCommand.Parameters.Add("@Id_user", SqlDbType.Int, 0, "Id_user"); 
      int newID = (int)selectCommand.ExecuteScalar(); 

      int User_ID = Convert.ToInt32(selectCommand.Parameters["@Id_user"].Value); 
      Session["Id_user"] = User_ID; 

      buserIdAuthenticated = true;     
      Session["userIdAuthenticated"] = buserIdAuthenticated; 
      Response.Redirect("../pages/Bienvenue.aspx"); 
     } 
    } 

    catch (SqlException ex) 
    { 
     lblMessage.Text = ex.Message; 
    } 

    finally 
    { 
     sqlConnection.Close(); 
    } 
    } 
} 
+10

'SCOPE_IDENTIY'! =' SCOPE_IDENTITY' –

+0

Я не вижу в параметрах '@ id_user', также вы должны объявить его как * output *. Посмотрите здесь информацию: http://msdn.microsoft.com/en-us/library/59x02y99(v=vs.110).aspx –

+0

[This] (http://stackoverflow.com/a/8389275/477878) может помочь. –

ответ

0

Вы не должны разделить запрос в двух запросах. Вы должны выбрать/установить результат в запросе вставки.

Я сделал пример для вас:

Первый метод возвращает одно значение, с использованием select

private void Method1() 
{ 
    string sEmail = "[email protected]"; 
    string passwordHash = "#[email protected]#[email protected]!#@[email protected]#!#@$!#@$!"; 
    string salt = "????"; 
    string sName = "John"; 

    using (SqlConnection sqlConnection = new SqlConnection(_connectionString)) 
     try 
     { 
      sqlConnection.Open(); 

      string insertStatement = "INSERT INTO [User] " 
             + "(email, hash, salt, name) " 
             + "VALUES (@email, @hash, @salt, @name)" 

             + "SELECT SCOPE_IDENTITY()"; 

      using (SqlCommand insertCommand = new SqlCommand(insertStatement, sqlConnection)) 
      { 

       insertCommand.Parameters.Add("@email", SqlDbType.VarChar, 50).Value = sEmail; 
       insertCommand.Parameters.Add("@hash", SqlDbType.VarChar, 50).Value = passwordHash; 
       insertCommand.Parameters.Add("@salt", SqlDbType.VarChar, 50).Value = salt; 
       insertCommand.Parameters.Add("@name", SqlDbType.VarChar, 50).Value = sName; 


       int userId = Convert.ToInt32(insertCommand.ExecuteScalar()); 
       Trace.WriteLine("User created with id: " + userId); 
      } 
     } 

     catch (SqlException ex) 
     { 
      Trace.WriteLine(ex.Message); 
      //lblMessage.Text = ex.Message; 
     } 
} 

Второй метод, определяющий параметр вывода, таким образом, вы можете вернуть несколько значений.

private void Method2() 
{ 
    string sEmail = "[email protected]"; 
    string passwordHash = "#[email protected]#[email protected]!#@[email protected]#!#@$!#@$!"; 
    string salt = "????"; 
    string sName = "John"; 

    using (SqlConnection sqlConnection = new SqlConnection(_connectionString)) 
     try 
     { 
      sqlConnection.Open(); 

      string insertStatement = "INSERT INTO [User] " 
             + "(email, hash, salt, name) " 
             + "VALUES (@email, @hash, @salt, @name)" 

             + "SET @user_id = SCOPE_IDENTITY()"; 

      using (SqlCommand insertCommand = new SqlCommand(insertStatement, sqlConnection)) 
      { 

       insertCommand.Parameters.Add("@email", SqlDbType.VarChar, 50).Value = sEmail; 
       insertCommand.Parameters.Add("@hash", SqlDbType.VarChar, 50).Value = passwordHash; 
       insertCommand.Parameters.Add("@salt", SqlDbType.VarChar, 50).Value = salt; 
       insertCommand.Parameters.Add("@name", SqlDbType.VarChar, 50).Value = sName; 

       insertCommand.Parameters.Add("@user_id", SqlDbType.Int).Direction = ParameterDirection.Output; 

       insertCommand.ExecuteNonQuery(); 

       int userId = Convert.ToInt32(insertCommand.Parameters["@user_id"].Value); 
       Trace.WriteLine("User created with id: " + userId); 
      } 
     } 

     catch (SqlException ex) 
     { 
      Trace.WriteLine(ex.Message); 
      //lblMessage.Text = ex.Message; 
     } 
} 

Лучшее, что вы можете сделать, это сделать, если запросы являются статическими, помещая эти запросы в хранимые процедуры. Это ускорит выполнение запросов.

0

Как описано в комментариях:

string insertStatement = "INSERT INTO [User] " 
           + "(email, hash, salt, name) " 
           + "VALUES (@email, @hash, @salt, @name);" 
           + "SELECT @id_user = SCOPE_IDENTIY();"; 

Должно быть:

string insertStatement = "INSERT INTO [User] " 
           + "(email, hash, salt, name) " 
           + "VALUES (@email, @hash, @salt, @name);" 
           + "SELECT SCOPE_IDENTITY() AS id_user;"; 

Чувствуете разницу между SCOPE_IDENTIY и SCOPE_IDENTITY.

Обратите внимание на обновление синтаксиса инструкции SELECT.

+0

Я сделал изменение теперь получил ошибку Должен объявить скалярную переменную "@id_user". – user3127986

+0

@Jay Я пытаюсь найти хороший ответ, чтобы извлечь scope_Identity(); я добавил следующие строки "SELECT SCOPE_IDENTITY() AS id_user;"; insertCommand.Parameters.Add ("@ id_user", SqlDbType.Int, 0 , "Id_user"); но я имею эту ошибку. Параметрированный запрос '(@email varchar (50), @ hash varchar (50), @ salt varchar (50), @ name' ожидает параметр '@id_user', который не был предоставлен. Любая идея? – user3127986

+0

Попробуйте использовать функцию ExecuteScalar? – cubitouch

Смежные вопросы