如何在C#中统计SQL Server表各列的NULL、非NULL及总行数
C#实现SQL Server表列的NULL/非NULL值统计
原有获取列名代码的修正
你提供的GetColumns方法存在两个问题:一是直接拼接SQL字符串有SQL注入风险,二是读取查询结果时仅获取了第一行数据,无法拿到所有列名。以下是修正后的版本:
using System.Collections.Generic; using System.Data; using System.Data.SqlClient; public List<string> GetColumns(string tableName) { var columns = new List<string>(); // 使用参数化查询避免SQL注入 var selectQuery = @"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TableName"; using (var conn = new SqlConnection(_sqlServerConnectionString.SqlServerConnectionString)) { conn.Open(); using (var cmd = new SqlCommand(selectQuery, conn)) { cmd.Parameters.AddWithValue("@TableName", tableName); using (var reader = cmd.ExecuteReader()) { // 循环读取所有列名 while (reader.Read()) { columns.Add(reader["COLUMN_NAME"].ToString()); } } } // using块会自动关闭连接,无需手动调用conn.Close() } return columns; }
实现列统计功能
要高效统计每列的总行数、NULL值数量和非NULL值数量,我们可以通过一次SQL查询获取所有列的统计数据,避免多次连接数据库。以下是完整实现:
1. 定义统计结果模型
public class ColumnStatistics { public string ColumnName { get; set; } public int TotalRows { get; set; } public int NullCount { get; set; } public int NonNullCount { get; set; } }
2. 统计方法实现
public List<ColumnStatistics> GetColumnStatistics(string tableName) { var columnStats = new List<ColumnStatistics>(); var columns = GetColumns(tableName); if (columns.Count == 0) return columnStats; // 构建统计SQL:COUNT(*)获取总行数,COUNT(列名)获取非NULL数量 var statsQueryParts = new List<string>(); // 先获取总行数(所有列总行数一致,只需计算一次) statsQueryParts.Add("COUNT(*) AS TotalRows"); // 为每个列添加非NULL统计 foreach (var column in columns) { statsQueryParts.Add($"COUNT({QuotedIdentifier(column)}) AS {QuotedIdentifier($"NonNull_{column}")}"); } var statsQuery = $"SELECT {string.Join(", ", statsQueryParts)} FROM {QuotedIdentifier(tableName)}"; using (var conn = new SqlConnection(_sqlServerConnectionString.SqlServerConnectionString)) { conn.Open(); using (var cmd = new SqlCommand(statsQuery, conn)) { using (var reader = cmd.ExecuteReader()) { if (reader.Read()) { int totalRows = reader.GetInt32(reader.GetOrdinal("TotalRows")); // 遍历每个列,计算NULL数量并封装结果 foreach (var column in columns) { int nonNullCount = reader.GetInt32(reader.GetOrdinal($"NonNull_{column}")); columnStats.Add(new ColumnStatistics { ColumnName = column, TotalRows = totalRows, NonNullCount = nonNullCount, NullCount = totalRows - nonNullCount }); } } } } } return columnStats; } // 辅助方法:为列名/表名添加引号,处理包含特殊字符或关键字的情况 private string QuotedIdentifier(string name) { return $"[{name}]"; }
3. 使用示例
// 调用统计方法 var stats = GetColumnStatistics("YourTableName"); // 输出结果 foreach (var stat in stats) { Console.WriteLine($"列名: {stat.ColumnName}"); Console.WriteLine($"总行数: {stat.TotalRows}"); Console.WriteLine($"NULL值数量: {stat.NullCount}"); Console.WriteLine($"非NULL值数量: {stat.NonNullCount}"); Console.WriteLine("---"); }
关键说明
- 避免SQL注入:所有与用户输入相关的表名、列名都通过
QuotedIdentifier方法添加方括号,同时原获取列名的方法使用了参数化查询。 - 高效查询:仅执行一次SQL查询就获取所有列的统计数据,相比逐列查询大幅提升效率。
- 资源自动释放:所有
SqlConnection、SqlCommand、SqlDataReader都使用using块,确保数据库资源被正确释放。
内容的提问来源于stack exchange,提问作者user989988
相关产品推荐
相关产品推荐

