【问题标题】:How do I dynamically count all rows that have a null value across all tables and columns in a database schema如何动态计算数据库架构中所有表和列中具有空值的所有行
【发布时间】:2013-02-28 14:40:28
【问题描述】:

我需要创建一个异常报告,查看特定架构中的所有表,然后计算列和行,并列出每列有多少条目包含 NULL 值。

不使用游标如何做到这一点?

例子:

People_Table 有 3 列(NAME、SURNAME、CONTACT_NO)
Entity_Table 有 5 列(ID、NAME、ADDRESS、TEL_NO、FAX_NO)

我需要生成一个输出,列出每个表和列名以及每个列中包含 NULL 值的记录数。

People_Table : NAME (4), SURNAME (9), CONTACT_NO (120)
Entity_Table : ID (0), NAME (4), ADDRESS (90), TEL_NO (120), FAX_NO (100)

请注意,输出可以是常规数据集格式,不需要看起来像条目的串联!我只是以这种方式列出它来描述数据输出。

这是针对随时间变化的动态数据库,作为在此阶段没有任何 NULL 条目的列,将来可能会有一个 NULL 条目,因此我需要对此进行跟踪。到目前为止,我已经为这个解决方案做了其他事情,这是我现在需要的最后一个。有什么建议吗??

【问题讨论】:

  • 使用游标有什么问题?

标签: database tsql count null isnull


【解决方案1】:

试试这个(虽然使用游标):

DECLARE @tbl sysname
DECLARE @col sysname
DECLARE @sql nvarchar(max)
DECLARE @cnt INT

CREATE TABLE #result
(
    tbl sysname,
    col sysname,
    nulls int
)

DECLARE crs CURSOR FOR 
select t.name, c.name
from sys.columns c
join sys.tables t on c.object_id = t.object_id

OPEN crs

FETCH NEXT FROM crs INTO @tbl, @col

WHILE @@FETCH_STATUS=0
BEGIN

    SET @sql = 'select @cntOUT=count(*)  from '+@tbl+' where '+@col+' is null'

    SET @cnt = 0
    exec sp_executesql @sql, N'@cntOUT INT OUTPUT', @cntOUT=@cnt OUTPUT

    INSERT INTO #result (tbl, col, nulls)
    VALUES (@tbl, @col, @cnt)


    FETCH NEXT FROM crs INTO @tbl, @col
END

CLOSE crs
DEALLOCATE crs

SELECT * FROM #result

DROP TABLE #result

【讨论】:

  • 感谢您的努力。出于性能原因,我需要防止使用游标,因为此脚本将插入具有任何格式的任何数据库中,并且它将返回相关详细信息。您的回复非常迅速,这让我对这个论坛更加满意。我现在要发布我的答案!
  • 天哪,现在我必须花时间将代码格式化为论坛要求。当我有时间这样做时,我会将我的答案放在这里。我也可以发布我的整个存储过程,但需要对其进行版权保护,因为这是一种检查整个数据仓库数据库一致性的简单方法,并且对任何开发人员都有好处。此 Proc 用于数据仓库环境
  • 所以你找到了一种不用光标的方法?很想知道您的解决方案。
  • 是的,我设法在没有光标的情况下做到了。我只是构建了一个临时表,并收集了使用 SQL 中的 sys 对象所需的所有信息。然后我添加了一个脚本参数,该参数连接了一个大字符串,该字符串构建了一个 UNION ALL Select Count(*) From @dbname.@SchemaName.@tablename@.@ColumnName 其中@ColumnName 为空。然后我将它链接到另一个临时表中我现有的列列表,然后“哇,哇”它就像一个魅力。这可以用于任何服务器上的任何数据库结构。
  • 我将很快发布我的整个脚本。有没有一种方法可以简单地保存 .sql 脚本文件,而无需我现在进入并根据此站点要求对其进行格式化?不是我的布局很差,只是代码很多,不习惯这个编码引擎……
【解决方案2】:
DECLARE @dbname VARCHAR(100) = 'dbname'
DECLARE @schemaName VARCHAR(100) = 'schemaname'
DECLARE @result TABLE ([NullValues] int,col VARCHAR(4000))

SELECT  @dbname dbname
        ,t.name tbl
        ,c.name col
INTO    #Temp1
FROM    sys.columns c
JOIN    sys.tables t ON 
        t.object_id = c.object_id
JOIN    sys.schemas s ON 
        s.schema_id = t.schema_id
WHERE   c.is_nullable = 1
AND     s.name in (@schemaName)

DECLARE @sql NVARCHAR(MAX) =
STUFF(
(
    SELECT  'UNION ALL SELECT Count(*) as [NullValues],''' + @dbname + '.' + @schemaName + '.' + tbl + '.' + col + ''' FROM ' + @dbname + '.' + @schemaName + '.' + tbl + ' WHERE ' + col + ' IS NULL '
    FROM    #Temp1
    FOR     XML PATH('')
), 1, 10, '   ')

INSERT @result
EXEC(@sql)

SELECT  [NullValues], col
INTO #Nulls
FROM    @result
WHERE   col IS NOT NULL AND [NullValues] > 0

SELECT
       [TABLE_CATALOG] + '.' + [TABLE_SCHEMA] + '.' + [TABLE_NAME] + '.' + [COLUMN_NAME] as SchemaTableColumn
      ,[TABLE_CATALOG] as 'Database'
      ,[TABLE_SCHEMA] as 'Schema'
      ,[TABLE_NAME] as 'TableName'
      ,[COLUMN_NAME]
      ,[ORDINAL_POSITION]
      ,[DATA_TYPE]
INTO #Temp2
  FROM [DW_LandingCR].[INFORMATION_SCHEMA].[COLUMNS]
  WHERE
    [TABLE_SCHEMA] = @schemaName
  ORDER BY TABLE_SCHEMA,TABLE_NAME,ORDINAL_POSITION

SELECT sc.name as [Schema],ta.name as [TableName],SUM(pa.rows) RowCnt
INTO #Temp3
 FROM sys.tables ta
 INNER JOIN sys.partitions pa
 ON pa.OBJECT_ID = ta.OBJECT_ID
 INNER JOIN sys.schemas sc
 ON ta.schema_id = sc.schema_id
 WHERE ta.is_ms_shipped = 0 
 AND pa.index_id IN (1,0)
 AND sc.name = @schemaName
 GROUP BY sc.name,ta.name
 ORDER BY sc.name,ta.name

Select 
    tp2.*,tp3.RowCnt 
Into #Detail
From 
    #Temp2 tp2 
    inner join #Temp3 tp3 on tp2.[Schema]=tp3.[Schema] and tp2.[TableName]=tp3.[TableName]

Select
    det.*,
    n.[NullValues]
From
    #Nulls n
    Inner Join #Detail det on det.SchemaTableColumn=n.col
Order By
    det.[Database],
    det.[Schema],
    det.TableName,
    det.[ORDINAL_POSITION]


Drop Table #Nulls
Drop Table #Detail
Drop Table #Temp1
Drop Table #Temp2
Drop Table #Temp3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多