Azure Synapse Dedicated SQL Pool统计指定表中各字段的空值、空字符串或零值比例

sql 复制代码
-- 创建临时表存储结果
CREATE TABLE #Results (
    DatabaseName NVARCHAR(128),
    TableName NVARCHAR(128),
    ColumnName NVARCHAR(128),
    DataType NVARCHAR(128),
    NullOrEmptyCount INT,
    TotalRows INT,
    Percentage DECIMAL(10,2)
);

DECLARE @db_name SYSNAME = DB_NAME();  -- 获取当前数据库名
DECLARE @table_name SYSNAME;
DECLARE @column_name SYSNAME;
DECLARE @data_type SYSNAME;
DECLARE @sql NVARCHAR(MAX);

-- 定义表游标
DECLARE table_cursor CURSOR FOR
SELECT TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE' 
  AND TABLE_CATALOG = @db_name;

OPEN table_cursor;

FETCH NEXT FROM table_cursor INTO @table_name;

WHILE @@FETCH_STATUS = 0
BEGIN
    -- 定义列游标
    DECLARE column_cursor CURSOR FOR
    SELECT COLUMN_NAME, DATA_TYPE 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = @table_name 
      AND TABLE_CATALOG = @db_name;

    OPEN column_cursor;
    FETCH NEXT FROM column_cursor INTO @column_name, @data_type;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        -- 构建动态SQL
        SET @sql = N'
        INSERT INTO #Results
        SELECT 
            ''' + @db_name + ''' AS DatabaseName,
            ''' + @table_name + ''' AS TableName,
            ''' + @column_name + ''' AS ColumnName,
            ''' + @data_type + ''' AS DataType,
            ';

        -- 根据数据类型处理逻辑
        IF @data_type IN ('varchar', 'nvarchar', 'char', 'nchar', 'text')
        BEGIN
            SET @sql += N'
            SUM(CASE WHEN ISNULL(TRIM([' + @column_name + ']), '''') = '''' THEN 1 ELSE 0 END),';
        END
        ELSE IF @data_type IN ('int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real')
        BEGIN
            SET @sql += N'
            SUM(CASE WHEN ISNULL([' + @column_name + '], 0) = 0 THEN 1 ELSE 0 END),';
        END
        ELSE
        BEGIN
            SET @sql += N'
            SUM(CASE WHEN [' + @column_name + '] IS NULL THEN 1 ELSE 0 END),';
        END

        -- 添加行数和百分比计算
        SET @sql += N'
            COUNT(*) AS TotalRows,
            ROUND(
                (SUM(CASE WHEN ';
        
        IF @data_type IN ('varchar', 'nvarchar', 'char', 'nchar', 'text')
            SET @sql += N'ISNULL(TRIM([' + @column_name + ']), '''') = '''' '
        ELSE IF @data_type IN ('int', 'bigint', 'smallint', 'tinyint', 'decimal', 'numeric', 'float', 'real')
            SET @sql += N'ISNULL([' + @column_name + '], 0) = 0 '
        ELSE
            SET @sql += N'[' + @column_name + '] IS NULL ';

        SET @sql += N'THEN 1 ELSE 0 END) * 100.0) / 
                NULLIF(COUNT(*), 0), 
                2
            )
        FROM ' + QUOTENAME(@table_name) + ';';

        -- 执行动态SQL
        EXEC sp_executesql @sql;

        FETCH NEXT FROM column_cursor INTO @column_name, @data_type;
    END

    CLOSE column_cursor;
    DEALLOCATE column_cursor;

    FETCH NEXT FROM table_cursor INTO @table_name;
END

CLOSE table_cursor;
DEALLOCATE table_cursor;

-- 查询最终结果
SELECT 
    DatabaseName,
    TableName,
    ColumnName,
    DataType,
    NullOrEmptyCount,
    TotalRows,
    Percentage
FROM #Results
ORDER BY TableName, ColumnName;

-- 清理临时表
DROP TABLE #Results;

代码说明:

  1. 临时表创建 :使用#Results临时表存储最终结果集

  2. 游标遍历

    • 外层游标遍历所有用户表
    • 内层游标遍历每个表的所有列
  3. 动态SQL构建

    • 根据列数据类型生成不同的统计逻辑
    • 字符串类型:使用TRIM()和空字符串判断
    • 数值类型:使用0值判断
    • 其他类型:直接判断NULL值
  4. 安全处理

    • 使用QUOTENAME()防止SQL注入
    • 使用NULLIF()处理除零错误
  5. 结果输出

    • 包含数据库名、表名、列名、数据类型
    • 统计空值/空字符串数量
    • 显示总行数和百分比

执行结果示例:

DatabaseName TableName ColumnName DataType NullOrEmptyCount TotalRows Percentage
MyDB Customer FirstName varchar 125 10000 1.25
MyDB Customer Age int 2300 10000 23.00
MyDB Order OrderDate datetime 45 5000 0.90

注意事项:

  1. 需要具有访问系统视图的权限
  2. 对大型表执行COUNT(*)可能影响性能
  3. 确保在正确的数据库上下文中执行
  4. 结果百分比保留两位小数
  5. 处理text类型字段时可能需要考虑性能影响
相关推荐
sbjdhjd1 小时前
从 assert 动态调用报错到临时文件链路:PHP 5.6 与 7.3 授权靶场中的短 payload 复盘 | (17字符绕过)
安全·网络安全·数据挖掘·开源·云计算·php·字符绕过
sbjdhjd1 小时前
从 7 字符文件名拼接到二维数组取值:PHP 无参函数限制下的受控靶场复盘 | (7字符绕过)
网络·nginx·安全·网络安全·云计算·php·apache
TDengine (老段)1 小时前
TDgpt 使用 — 部署、SQL、算法
大数据·数据库·sql·算法·时序数据库·tdengine·涛思数据
程序员小羊!2 小时前
医疗数据仓库ODS层敏感信息防护实战:7大关键策略
数据仓库
2501_933670794 小时前
内部审计校招的数据化趋势:SQL、Excel、Power BI和证书选择
数据库·sql·excel
欢迎来到祖安!7 小时前
企业微信 API 接口能力介绍:支持消息收发、图片发送、表情互动、联系人管理等多场景应用
java·前端·数据仓库·spring cloud·企业微信
mengge.cloud15 小时前
0909华为云计算类综合服务小白实验教程
linux·运维·服务器·网络·华为云·云计算
QYR-分析17 小时前
蓝海赛道高速扩容!全球小型观察ROV市场格局、细分场景与发展趋势分析
大数据·运维·云计算
weixin_4935036717 小时前
商会小程序附件上传:分片上传 + OSS 直传完整实现(Vue3 + 阿里云 OSS 实战)
阿里云·小程序·云计算
小袁拒绝摆烂18 小时前
一条 SQL 从 30 秒到 300 毫秒:聊聊 MySQL 的 Hash Join
sql·mysql·哈希算法