简体   繁体   中英

SQLHelper Class - Insert/Update method return inserted ID @@identity

I have an SQL helper Class for my application, everything works nice as it should be, but in some code, I need to get the inserted ID using @@identity, what is the best way to do this??

Here is My method in my SQL helper class:

public static void InsertUpdate_Data(string sql, CommandType cmdType, params SqlParameter[] parameters)
        {
            using (SqlConnection connStr = new SqlConnection(ConnectionString))
            using (SqlCommand cmd = new SqlCommand(sql, connStr))
            {
                cmd.CommandType = cmdType;
                cmd.Parameters.AddRange(parameters);
                try
                {
                    cmd.Connection.Open();
                    cmd.ExecuteNonQuery();
                }
                catch (SqlException ex)
                {
                    //log to a file or Throw a message ex.Message;
                    MessageBox.Show("Error: " + ex.Message);
                }
            }
        }

And this is how I use it:

DBConn.InsertUpdate_Data("customer_add", CommandType.StoredProcedure,
               new SqlParameter[]
               {
                new SqlParameter("@name", txt_name.Text.Trim()),
                new SqlParameter("@gender", Gender_comb.Text),
                new SqlParameter("@b_o_date", DOBTimePicker1.Value ),
                new SqlParameter("@phone", Phone_txt.Text.Trim()),
                new SqlParameter("@address", string.IsNullOrEmpty(Location_txt.Text) ? (object)DBNull.Value : Location_txt.Text.Trim()),
                new SqlParameter("@note", string.IsNullOrEmpty(Note_txt.Text) ? (object)DBNull.Value : Note_txt.Text.Trim())
               }

And also what is the best way to use SQL transactions in some code.

Thank you.

Don't use @@IDENTITY , it's unreliable .

The stored procedure should have, on the line immediately following the insert, SELECT SCOPE_IDENTITY() . Then you can use cmd.ExecuteScalar as mentioned.


For transactions, you have two options.

Either use conn.BeginTransaction() and don't forget to open the connection first, add transaction to command.Transaction , and put the transaction in a using block:

public static int InsertUpdate_Data(string sql, CommandType cmdType, params SqlParameter[] parameters)
        {
            try
            {
                using (SqlConnection conn = new SqlConnection(ConnectionString))
                {
                    conn.Open()
                    using (var tran = conn.BeginTransaction())
                    using (SqlCommand cmd = new SqlCommand(sql, connStr, tran))
                    {
                        cmd.CommandType = cmdType;
                        cmd.Parameters.AddRange(parameters);
                        var result = (int)cmd.ExecuteScalar();
                        tran.Commit();
                        return result;
                    }
                }
            }
            catch (SqlException ex)
            {
                //log to a file or Throw a message ex.Message;
                MessageBox.Show("Error: " + ex.Message);
                throw;
            }
        }

The other, possibly better, option is to use BEGIN TRANSACTION; and COMMIT TRANSACTION; in the procedure. Don't bother with TRY/CATCH/ROLLBACK , just put at the top of the procedure SET XACT_ABORT ON; , this guarantees a rollback on the event of an error.


Other notes:

  1. Use proper types, length and precision on your SqlParameter s, it will help with performance.
  2. Do not block the thread with things like MessageBox while the connection is open. Log the exception and check it after. Or better, do what I did above and try/catch around the connection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM