[英]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
. 有超过1500行,因此出于性能原因需要TRUNCATE TABLE
。
The flow of my method is: 我的方法的流程是:
My Question is: Can I successfully perform the above using SqlConnection? 我的问题是:我可以使用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. 因为我正在截断表并且基本上执行> 1500个插入,所以我有点犹豫是否只是为了找出而运行代码。 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: 您应该将事务放在using
块中并删除它:
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. DELETE FROM MyTable
不会这样做。 It allows for concurrent (read) access. 它允许并发(读取)访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.