Retrieving the last inserted ID using scope_Identity()

守給你的承諾、 提交于 2021-01-28 05:31:40

问题


I am trying to get the last ID inserted using the SCOPE_IDENTITY but I got an error. I am using SQL server 2012 with Visual Studio Express 2013

Here is my code

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();
    }
  }
}

I want to catch the last user_id which was define as Identity for the auto-increment.

Here is the error I got

An exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll but was not handled in user code.

Additional information: An SqlParameter with ParameterName '@id_user' is not contained by this SqlParameterCollection.

I decided to splitted the two request. 1 insert and 1 select

    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();
    }
  }
 }

回答1:


You should not split the query in two queries. You should select/set the result within the insert query.

I made an example for you:

The first method is returning a single value with the use of select

private void Method1()
{
    string sEmail = "test@test.com";
    string passwordHash = "#$@#$@!#@$$@#!#@$!#@$!";
    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;
        }
}

The second method is defining an output parameter, this way you can return multiple values.

private void Method2()
{
    string sEmail = "test@test.com";
    string passwordHash = "#$@#$@!#@$$@#!#@$!#@$!";
    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;
        }
}

The best you can do is, if the queries are static, putting these queries within stored procedures. This will speed-up the queries.




回答2:


As described in the comments :

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

Should be :

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

See the difference between SCOPE_IDENTIY and SCOPE_IDENTITY.

And note the update to the SELECT statement syntax.



来源:https://stackoverflow.com/questions/21388358/retrieving-the-last-inserted-id-using-scope-identity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!