declare @tab_name varchar(100)
declare @col_name varchar(100)
declare @sqlquery nvarchar(max)
declare cursor_table cursor
for
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES --where table_name!='tab'
open cursor_table
fetch next from cursor_table into @tab_name
while @@fetch_status = 0
begin
declare cursor_count cursor
for
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tab_name
open cursor_count
fetch next from cursor_count into @col_name
while @@FETCH_STATUS =0
begin
set @sqlquery='
select '+''''+@tab_name+''''+','+''''+ @col_name+''''+',count('+@col_name+') as count from '+@tab_name+' where ISNULL('+@col_name+','''') !='''' '
print @sqlquery
exec sp_executesql @sqlquery
fetch next from cursor_count into @col_name
End
CLOSE cursor_count
DEALLOCATE cursor_count
print @tab_name
fetch next from cursor_table into @tab_name
end
CLOSE cursor_table
DEALLOCATE cursor_table
答案 0 :(得分:0)
如果我“需要”获得每个列,每个表的所有空值的计数,我会这样接近它。
这是非常低效的查询,可能需要一段时间才能执行,因为您必须对所有非索引字段执行多个全表扫描。对于本练习,我建议您将其限制在几张桌子上。
SELECT CommandOrder=1,'DECLARE @TEMP TABLE(TableName NVARCHAR(100), ColumnName NVARCHAR(100), NullRecordCount INT)'
UNION
SELECT CommandOrder=3,
'INSERT @TEMP SELECT '''+S.Name+'.'+T.Name+''','''+C.Name+''', COUNT(*) FROM '+S.Name+'.'+T.Name+' WHERE COALESCE('+C.Name+',NULL)=NULL'
FROM
SYS.Columns C
INNER JOIN SYS.Tables T ON C.object_id = T.object_id
INNER JOIN SYS.Schemas S ON T.schema_id = S.schema_id
UNION
SELECT CommandOrder=4,'SELECT * FROM @TEMP T WHERE NullRecordCount > 0 ORDER BY TableName,ColumnName'
答案 1 :(得分:0)
如果要求至少将其最小化为一个光标,请使用此方法。
如果你真的必须使用游标,请使用FAST_FORWARD游标选项。
declare @tab_name varchar(100)
declare @col_name varchar(100)
declare @sqlquery nvarchar(max)
DECLARE @mainTable TABLE(
Id INT IDENTITY(1,1) PRIMARY KEY,
TABLE_NAME Varchar(500)
)
--GET TABLES data into main table
INSERT INTO @mainTable
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
DECLARE @startTables INT = 1
DECLARE @finalTables INT = 0
SELECT @finalTables = MAX(Id) FROM @mainTable
-- Do a while loop over id
WHILE @startTables <= @finalTables
BEGIN
-- Get the table name
SELECT @tab_name = TABLE_NAME FROM @mainTable WHERE Id = @startTables
-- Initialize cursor
declare cursor_count cursor
for
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tab_name
open cursor_count
fetch next from cursor_count into @col_name
while @@FETCH_STATUS =0
begin
set @sqlquery='select '+''''+@tab_name+''''+','+''''+ @col_name+''''+',count('+@col_name+') as count from '+@tab_name+' where ISNULL('+@col_name+','''') !='''' '
print @sqlquery
exec sp_executesql @sqlquery
fetch next from cursor_count into @col_name
End
CLOSE cursor_count
DEALLOCATE cursor_count
print @tab_name
SET @startTables = @startTables + 1
END
根本不使用光标,请使用此功能。
declare @tab_name varchar(100)
declare @col_name varchar(100)
declare @sqlquery nvarchar(max)
-- Table stores Id, table name, Query in one go.
DECLARE @secondaryTable TABLE(
Id INT IDENTITY(1,1) PRIMARY KEY,
TABLE_NAME Varchar(500),
Query Varchar(8000)
)
INSERT INTO @secondaryTable
SELECT a.TABLE_NAME, 'select '+''''+a.TABLE_NAME+''''+','+''''+ b.COLUMN_NAME+''''+',count('+b.COLUMN_NAME+') as count from '+a.TABLE_NAME+' where ISNULL('+b.COLUMN_NAME+','''') !='''' '
FROM INFORMATION_SCHEMA.TABLES a INNER JOIN INFORMATION_SCHEMA.COLUMNS b ON a.TABLE_NAME = b.TABLE_NAME
--SELECT * FROM @secondaryTable
DECLARE @startTables INT = 1
DECLARE @finalTables INT = 0
SELECT @finalTables = MAX(Id) FROM @secondaryTable
-- Loop through the table, get the table name and query. Execute the query.
WHILE @startTables <= @finalTables
BEGIN
SELECT @tab_name = TABLE_NAME, @sqlquery = Query FROM @secondaryTable WHERE Id = @startTables
print @sqlquery
exec sp_executesql @sqlquery
print @tab_name
SET @startTables = @startTables + 1
END