我需要创建一个异常报告,查看特定模式中的所有表,然后对列和行进行计数,并列出每列包含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条目,所以我需要跟踪它。到目前为止,我已经为这个解决方案做了其他的事情,这是我现在需要的最后一个。有什么建议??
答案 0 :(得分:0)
试试这个(尽管使用游标):
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
答案 1 :(得分:0)
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