事务,表截断和参数化SQL查询

时间:2015-08-17 14:24:36

标签: c# sql asp.net sql-server

我必须清除表格中的所有内容并重新加载新数据。有超过1500行,因此出于性能原因,有必要TRUNCATE TABLE

我方法的流程是:

  1. 开始交易
  2. 截断表格
  3. 获取最新数据
  4. 使用SQL参数化值
  5. 插入所有行
  6. 获取数据&&插入成功? 提交事务:回滚
  7. 我的问题是:我可以使用SqlConnection成功执行上述操作吗?因为我正在截断表并基本上执行> 1500插入,我有点犹豫,只是为了找出来运行代码。我试过在网上看,虽然我发现了类似的问题,但我觉得它们并不是我的具体情况。

    以下是我为执行所需操作而开发的方法:

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

1 个答案:

答案 0 :(得分:0)

这可以阻止任何错误。

您应该将交易放在using块中并删除它:

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

因为这没有任何作用。

请注意,截断表会使用并发快照读取器进行架构修改锁定和混乱。 DELETE FROM MyTable不这样做。它允许并发(读取)访问。