如何在C#控制台应用(SMTP)中将多库SQL查询结果格式化到邮件正文
入门指导:多数据库查询+结果合并成邮件表格
早上好呀!别担心问题基础——大家都是从新手过来的,而且你已经提前做了调研,这点超棒👍 结合你的情况(SQL经验更丰富,已有SMTP类库),咱们一步步来拆解问题:
1. 从App.config读取并动态修改连接字符串
因为所有数据库都在同一台服务器,咱们不需要维护7个独立的连接字符串,只需要读取基础连接串,然后动态替换Database参数即可:
// 先引用System.Configuration程序集,然后读取基础连接串 string baseConnString = ConfigurationManager.ConnectionStrings["YourConnectionName"].ConnectionString; // 定义7个数据库名称列表 List<string> dbNames = new List<string> { "DB1", "DB2", "DB3", "DB4", "DB5", "DB6", "DB7" };
替换数据库名的小技巧:用正则表达式精准修改Database=部分,避免破坏连接串其他参数:
Regex dbRegex = new Regex(@"Database=([^;]+);"); foreach (string dbName in dbNames) { string currentConnString = dbRegex.Replace(baseConnString, $"Database={dbName};"); // 接下来用这个currentConnString连接对应数据库 }
2. 遍历数据库执行查询,合并结果
你SQL经验丰富,核心查询逻辑可以自己调整,这里给你C#层面的实现框架:
方式1:用DataTable合并(快速上手)
适合不想定义实体类的场景,直接用DataTable存结果并合并:
// 初始化空表存所有结果 DataTable mergedResults = new DataTable(); foreach (string dbName in dbNames) { string currentConnString = dbRegex.Replace(baseConnString, $"Database={dbName};"); using (SqlConnection conn = new SqlConnection(currentConnString)) { conn.Open(); // 替换成你的SQL查询语句 string sqlQuery = "SELECT Column1, Column2, Column3 FROM YourTable WHERE YourCondition;"; using (SqlCommand cmd = new SqlCommand(sqlQuery, conn)) using (SqlDataAdapter adapter = new SqlDataAdapter(cmd)) { DataTable tempTable = new DataTable(); adapter.Fill(tempTable); // 新增一列标记来源数据库,方便邮件里区分数据归属 tempTable.Columns.Add("来源数据库", typeof(string)).DefaultValue = dbName; // 合并到总表:第一个表直接赋值,后续表追加行 if (mergedResults.Rows.Count == 0) { mergedResults = tempTable.Copy(); } else { mergedResults.Merge(tempTable); } } } }
方式2:用强类型实体类(规范易维护)
如果习惯用面向对象的方式,可以先定义对应查询结果的实体类:
public class QueryResult { public string Column1 { get; set; } public int Column2 { get; set; } public DateTime Column3 { get; set; } public string SourceDatabase { get; set; } }
然后遍历查询时把数据映射到实体类,存入集合:
List<QueryResult> allResults = new List<QueryResult>(); // 省略连接串替换部分,直接在查询后映射数据 using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { allResults.Add(new QueryResult { Column1 = reader["Column1"].ToString(), Column2 = (int)reader["Column2"], Column3 = (DateTime)reader["Column3"], SourceDatabase = dbName }); } }
3. 把合并结果转换成美观的HTML表格
邮件正文要呈现整洁的表格,推荐用HTML格式。这里给你一个快速转换DataTable到HTML表格的方法:
private string ConvertDataTableToHtml(DataTable table) { string html = "<table border='1' cellpadding='4' cellspacing='0' style='border-collapse: collapse; width: 100%;'>"; // 生成表头(加浅灰色背景区分) html += "<tr style='background-color: #f2f2f2;'>"; foreach (DataColumn col in table.Columns) { html += $"<th style='text-align: left;'>{col.ColumnName}</th>"; } html += "</tr>"; // 生成表体行 foreach (DataRow row in table.Rows) { html += "<tr>"; foreach (var item in row.ItemArray) { html += $"<td>{item.ToString()}</td>"; } html += "</tr>"; } html += "</table>"; return html; }
如果用的是实体类集合,逻辑类似:遍历集合生成对应的<tr>和<td>标签即可。
4. 调用你的SMTP类库发送邮件
假设你的SMTP类库有一个发送HTML邮件的方法,直接把生成的HTML表格传进去就行:
string emailBody = ConvertDataTableToHtml(mergedResults); // 调用你已有的发送方法 YourSmtpLibrary.SendHtmlEmail("收件人邮箱地址", "多数据库查询结果汇总", emailBody);
小提示(避免踩坑)
- 异常处理:给每个数据库的查询加
try-catch,比如某个库查询失败时,记录错误并继续处理其他库,不要直接崩溃:try { // 数据库查询逻辑 } catch (Exception ex) { // 可以把错误信息加到邮件末尾,或者写入日志 Console.WriteLine($"查询数据库{dbName}失败:{ex.Message}"); } - 连接字符串安全:生产环境记得加密App.config里的连接串,可以用
aspnet_regiis.exe工具实现。
内容的提问来源于stack exchange,提问作者mathew paton
相关产品推荐
相关产品推荐

