简体   繁体   中英

Transaction, Table Truncate and Parametrized SQL Query

I have to clear everything in a table and reload with fresh data. There are over 1500 rows, so for performance reasons it is necessary to TRUNCATE TABLE .

The flow of my method is:

  1. Begin Transaction
  2. Truncate the table
  3. Get fresh data
  4. Insert all rows using SQL parameterized values
  5. Getting Data && Inserts successful ? Commit Transaction : Rollback

My Question is: Can I successfully perform the above using SqlConnection? Because I am truncating tables and essentially performing > 1500 Inserts, I am a little bit hesitant to just run the code in an effort to find out. I have tried looking online and although I have found similar questions, I feel that they are not specific to my situation.

Here is the method I have developed to perform the required actions:

        public static void InsertCourseLookup(List<Course> courses)
        {
            using (SqlConnection connection = new SqlConnection(ConnectionString))
            {
                connection.Open();

                using (SqlCommand command = connection.CreateCommand())
                {
                    SqlTransaction transaction = connection.BeginTransaction("CourseLookupTransaction");

                    command.Connection = connection;
                    command.Transaction = transaction;
                    command.CommandTimeout = 300;

                    try
                    {
                        command.CommandText = "TRUNCATE TABLE course_info";
                        command.ExecuteNonQuery();

                        foreach (Course course in courses)
                        {
                            if (course == null)
                            {
                                throw new ArgumentException("course cannot be null");
                            }

                            ContentData courseData = GlobalHelper.GetContentData(course.ContentId);

                            if (courseData == null)
                            {
                                throw new Exception(string.Format("Missng ContentData for course '{0}'", course.Title));
                            }
                            // checks if row is already in table, if it is check.ContentId will be greater than 0
                            CourseLookup check = CourseHelper.GetCourseLookup(course.DatabaseId);

                            string sql = string.Empty;

                            if (check.ContentID > 0)
                            {
                                sql = @"
                                    UPDATE  course_info
                                    SET     content_id = @content_id,
                                            name = @name,
                                            code = @code,
                                            description = @description,
                                            url = @url,
                                            meta_keywords = @meta_keywords,
                                            meta_description = @meta_description
                                    WHERE   course_id = @course_id";
                            }
                            else
                            {
                                sql = @"
                                    INSERT INTO course_info(course_id, content_id, name, code, description, url, meta_keywords, meta_description)
                                    VALUES(@course_id, @content_id, @name, @code, @description, @url, @meta_keywords, @meta_description)";
                            }

                            string metaKeywords = string.Empty;
                            string metaDescription = string.Empty;

                            if (courseData.MetaData != null)
                            {
                                for (int i = 0; i < courseData.MetaData.Length; i++)
                                {
                                    if (courseData.MetaData[i].Id == ConfigData.Metadata.MetaKeywordsID)
                                    {
                                        metaKeywords = DataHelper.TruncateString(courseData.MetaData[i].Text, 500);
                                    }
                                    else if (courseData.MetaData[i].Id == ConfigData.Metadata.MetaDescriptionID)
                                    {
                                        metaDescription = DataHelper.TruncateString(courseData.MetaData[i].Text, 500);
                                    }
                                }
                            }

                            command.CommandText = sql;
                            command.Parameters.AddRange(
                                new SqlParameter[] {
                                    new SqlParameter("@course_id", course.DatabaseId),
                                    new SqlParameter("@content_id", course.ContentId),
                                    new SqlParameter("@name", course.Title),
                                    new SqlParameter("@code", course.Code),
                                    new SqlParameter("@description", course.Description),
                                    new SqlParameter("@url", courseData.Quicklink),
                                    new SqlParameter("@meta_keywords", metaKeywords),
                                    new SqlParameter("@meta_description", metaDescription)
                                }
                            );
                            command.ExecuteNonQuery();
                            command.Parameters.Clear();
                        }

                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();
                        Log.Error(string.Format("Unable to reload course lookup table: {0}", ex.Message));
                    }

                }
            }
        }

This will work barring any bugs.

You should put the transaction in a using block and delete this:

catch (Exception ex)
{
    transaction.Rollback();
    Log.Error(string.Format("Unable to reload course lookup table: {0}", ex.Message));
}

Because this does nothing.

Note, that truncating a table takes schema modification locks and messes with concurrent snapshot readers. DELETE FROM MyTable does not do that. It allows for concurrent (read) access.

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