通过将 C# 函数应用于另一列来更新 sql table 列
Update sql table column by applying a C# function to another column
我需要通过将定义的函数应用到该列来更新 table 列。
例如使用 MySqlCommand。
例如。我有一个 C# 定义的函数来清理文本 string GetCleanText(string text_to_clean)
,在我的一个 table 中,我有一列 fullTxt
包含要清理的文本,另一列 txt
现在是空的。
我的结果应该是:txt = GetCleanText(fullTxt)
。
我尝试使用 foreach
循环,但它太庞大了,因为我的 table.
中有几行
这是我的代码:
// Get all entries in the log table that have the html log and do not have text answers
MySqlCommand request1 = new MySqlCommand("SELECT * FROM my_table WHERE fullTxt IS NOT NULL AND txt IS NULL", conn);
// loop over results and clean the text entries
List<List<string>> tobefilled = new List<List<string>>();
using (MySqlDataReader r = request1.ExecuteReader())
{
while (r.Read())
{
string id = r.GetString("id");
string fullTxt = r.GetString("fullTxt");
string txt = this.GetCleanText(fullTxt);
tobefilled.Add(new List<string>() { id, txt });
}
}
System.Console.WriteLine($"{tobefilled.Count} to be updated ...");
// Update all entries in the log table that have the html log and do not have text answers
MySqlCommand request2 = new MySqlCommand("UPDATE my_table SET txt = @txt WHERE id = @id", conn);
request2.Parameters.AddWithValue("@txt", "");
request2.Parameters.AddWithValue("@id", "");
foreach (List<string> elem in tobefilled)
{
request2.Parameters["@txt"].Value = elem[1];
request2.Parameters["@id"].Value = elem[0];
request2.ExecuteNonQuery();
}
我不知道这种方法是否干净,但它工作得更快:
using System.Collections.Generic;
using System.Text;
using HtmlAgilityPack;
using MySql.Data.MySqlClient;
namespace DatabaseMigrations.MigrationScripts
{
class MigrationScript
{
/// <summary>
/// Take a string having html formatted content, and extract raw text
/// </summary>
/// <param name="html">input html string</param>
/// <returns>cleaned text in a string</returns>
public string GetCleanText(string html)
{
// parse the html in TxtMessage to extract text only
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
var htmlNodes = htmlDoc.DocumentNode.SelectNodes("/"); // all nodes in the html
string txtMessage = (htmlNodes[0].InnerText).Trim();
return txtMessage;
}
/// <summary>
/// Fill the txt column of previous bot logs with the parsed html content from the fullTxt column
/// </summary>
/// <param name="conn"></param>
public override void ApplyDataMigrationOperations(MySqlConnection conn)
{
// Get all entries in the log table that have the html log and do not have text answers
MySqlCommand request1 = new MySqlCommand("SELECT * FROM logmessagefrombot WHERE fullTxt IS NOT NULL AND txt IS NULL", conn);
// loop over results and clean the text entries
List<List<string>> tobefilled = new List<List<string>>();
using (MySqlDataReader r = request1.ExecuteReader())
{
while (r.Read())
{
string id = r.GetString("id");
string fullTxt = r.GetString("fullTxt");
string txt = this.GetCleanText(fullTxt);
tobefilled.Add(new List<string>() { id, txt });
}
}
System.Console.WriteLine($"{tobefilled.Count} to be updated ...");
// Update all entries in the log table that have the html log and do not have text answers
StringBuilder sb = new StringBuilder();
string cases = " WHEN @id THEN \"@txt\" ";
List<string> ids = new List<string>();
sb.Append("UPDATE logmessagefrombot SET txt = ( CASE id ");
if (tobefilled.Count > 0)
{
foreach (List<string> elem in tobefilled)
{
sb.Append(cases.Replace("@id", elem[0]).Replace("@txt", elem[1].Replace("\n", " ").Replace("\"", "''")));
ids.Add(elem[0]);
}
sb.Append("ELSE txt ");
sb.Append("END )");
sb.Append("WHERE id IN ( ");
sb.Append(string.Join(",", ids.ToArray()) + ")");
MySqlCommand request2 = new MySqlCommand(sb.ToString(), conn);
request2.ExecuteNonQuery();
}
}
}
}
使用 StringBuilder
构建的结果查询太长,但它有效。
我需要通过将定义的函数应用到该列来更新 table 列。
例如使用 MySqlCommand。
例如。我有一个 C# 定义的函数来清理文本 string GetCleanText(string text_to_clean)
,在我的一个 table 中,我有一列 fullTxt
包含要清理的文本,另一列 txt
现在是空的。
我的结果应该是:txt = GetCleanText(fullTxt)
。
我尝试使用 foreach
循环,但它太庞大了,因为我的 table.
这是我的代码:
// Get all entries in the log table that have the html log and do not have text answers
MySqlCommand request1 = new MySqlCommand("SELECT * FROM my_table WHERE fullTxt IS NOT NULL AND txt IS NULL", conn);
// loop over results and clean the text entries
List<List<string>> tobefilled = new List<List<string>>();
using (MySqlDataReader r = request1.ExecuteReader())
{
while (r.Read())
{
string id = r.GetString("id");
string fullTxt = r.GetString("fullTxt");
string txt = this.GetCleanText(fullTxt);
tobefilled.Add(new List<string>() { id, txt });
}
}
System.Console.WriteLine($"{tobefilled.Count} to be updated ...");
// Update all entries in the log table that have the html log and do not have text answers
MySqlCommand request2 = new MySqlCommand("UPDATE my_table SET txt = @txt WHERE id = @id", conn);
request2.Parameters.AddWithValue("@txt", "");
request2.Parameters.AddWithValue("@id", "");
foreach (List<string> elem in tobefilled)
{
request2.Parameters["@txt"].Value = elem[1];
request2.Parameters["@id"].Value = elem[0];
request2.ExecuteNonQuery();
}
我不知道这种方法是否干净,但它工作得更快:
using System.Collections.Generic;
using System.Text;
using HtmlAgilityPack;
using MySql.Data.MySqlClient;
namespace DatabaseMigrations.MigrationScripts
{
class MigrationScript
{
/// <summary>
/// Take a string having html formatted content, and extract raw text
/// </summary>
/// <param name="html">input html string</param>
/// <returns>cleaned text in a string</returns>
public string GetCleanText(string html)
{
// parse the html in TxtMessage to extract text only
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
var htmlNodes = htmlDoc.DocumentNode.SelectNodes("/"); // all nodes in the html
string txtMessage = (htmlNodes[0].InnerText).Trim();
return txtMessage;
}
/// <summary>
/// Fill the txt column of previous bot logs with the parsed html content from the fullTxt column
/// </summary>
/// <param name="conn"></param>
public override void ApplyDataMigrationOperations(MySqlConnection conn)
{
// Get all entries in the log table that have the html log and do not have text answers
MySqlCommand request1 = new MySqlCommand("SELECT * FROM logmessagefrombot WHERE fullTxt IS NOT NULL AND txt IS NULL", conn);
// loop over results and clean the text entries
List<List<string>> tobefilled = new List<List<string>>();
using (MySqlDataReader r = request1.ExecuteReader())
{
while (r.Read())
{
string id = r.GetString("id");
string fullTxt = r.GetString("fullTxt");
string txt = this.GetCleanText(fullTxt);
tobefilled.Add(new List<string>() { id, txt });
}
}
System.Console.WriteLine($"{tobefilled.Count} to be updated ...");
// Update all entries in the log table that have the html log and do not have text answers
StringBuilder sb = new StringBuilder();
string cases = " WHEN @id THEN \"@txt\" ";
List<string> ids = new List<string>();
sb.Append("UPDATE logmessagefrombot SET txt = ( CASE id ");
if (tobefilled.Count > 0)
{
foreach (List<string> elem in tobefilled)
{
sb.Append(cases.Replace("@id", elem[0]).Replace("@txt", elem[1].Replace("\n", " ").Replace("\"", "''")));
ids.Add(elem[0]);
}
sb.Append("ELSE txt ");
sb.Append("END )");
sb.Append("WHERE id IN ( ");
sb.Append(string.Join(",", ids.ToArray()) + ")");
MySqlCommand request2 = new MySqlCommand(sb.ToString(), conn);
request2.ExecuteNonQuery();
}
}
}
}
使用 StringBuilder
构建的结果查询太长,但它有效。