Sql 在表循环中创建列循环以计算数据库中所有字段的填充率
我有两个数据库,超过400个表,我必须计算填充率。我有一个循环用于计算表中所有列的填充率,但如何才能对数据库中的所有表执行此操作??请帮忙! 我正在使用SQL Server 下面是循环表中所有列以计算填充率的代码-Sql 在表循环中创建列循环以计算数据库中所有字段的填充率,sql,sql-server,loops,fill,rate,Sql,Sql Server,Loops,Fill,Rate,我有两个数据库,超过400个表,我必须计算填充率。我有一个循环用于计算表中所有列的填充率,但如何才能对数据库中的所有表执行此操作??请帮忙! 我正在使用SQL Server 下面是循环表中所有列以计算填充率的代码- DECLARE @Table NVARCHAR(max) = 'dbo.[TableName]' ,@MetaTable NVARCHAR(128) = '#TempTable' ,@ColumnName NVARCHAR(128) ,@Iterator INT =
DECLARE @Table NVARCHAR(max) = 'dbo.[TableName]'
,@MetaTable NVARCHAR(128) = '#TempTable'
,@ColumnName NVARCHAR(128)
,@Iterator INT = 1
,@SQL1 NVARCHAR(MAX)
SELECT c.NAME
,c.COLUMN_ID
,ROW_NUMBER() OVER (ORDER BY COLUMN_ID) AS RN
INTO #Cols
FROM SYS.COLUMNS c
WHERE c.OBJECT_ID = OBJECT_ID(@Table);
WHILE @Iterator <= (SELECT ISNULL(MAX(RN),0) FROM #Cols)
BEGIN
SET @ColumnName = (SELECT NAME FROM #Cols WHERE RN = @Iterator)
SET @SQL1 = 'INSERT INTO ' + @MetaTable + ' (Table_Name, Column_Name,
Fill_Rate) '
+ 'SELECT ''' + REPLACE(@Table,'DBO.','') + ''', ''' +
@ColumnName + ''', 100 * CONVERT(DECIMAL(8,3), SUM(CASE WHEN [' +
@ColumnName + '] IS NULL THEN 0 ELSE 1 END)) / COUNT(1) AS [' +
@ColumnName + '_fill]' + ' FROM ' + @Table
EXEC sp_executesql @SQL1
SET @Iterator += 1
END
我建议使用光标来完成这个简洁的小任务:
CREATE TABLE #MetaTable (
TABLE_SCHEMA sysname,
TABLE_NAME sysname,
COLUMN_NAME sysname,
fill_rate float NULL);
DECLARE
@schema sysname,
@table sysname,
@column sysname,
@sql nvarchar(max);
DECLARE column_cusor CURSOR FAST_FORWARD FOR
SELECT s.name, t.name, c.name
FROM sys.schemas s
INNER JOIN sys.tables t ON s.schema_id = t.schema_id
INNER JOIN sys.columns c ON t.object_id = c.object_id;
OPEN column_cusor;
FETCH NEXT FROM column_cusor INTO @schema, @table, @column;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = 'SELECT ' + QUOTENAME(@schema, '''')
+ ', ' + QUOTENAME(@table, '''')
+ ', ' + QUOTENAME(@column, '''')
+ ', ' + '100.0 * SUM(CASE WHEN ' + QUOTENAME(@column)
+ ' IS NULL THEN 0 ELSE 1 END) /'
+ ' CASE WHEN COUNT(*) = 0 THEN 1 ELSE COUNT(*) END'
+ ' FROM ' + QUOTENAME(@schema) + '.' + QUOTENAME(@table);
INSERT INTO #MetaTable (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, fill_rate)
EXEC (@sql);
FETCH NEXT FROM column_cusor INTO @schema, @table, @column;
END
CLOSE column_cusor;
DEALLOCATE column_cusor;
SELECT * FROM #MetaTable;
您使用的是哪种数据库管理系统?该代码是特定于产品的。不建议SQL Server管理人员直接研究系统表,它们可能会在下一个SQL Server版本中更改。取而代之的是,在模式视图中使用信息。对于列,使用信息\u SCHEMA.columns;对于表,使用信息\u SCHEMA.tables。COLUMNview还包含一个序号位置,因此您不需要为它们指定行号。@WolfgangKai的信息架构视图并不总是准确的,也不总是包含所有信息。好奇您在哪里听说不应该使用sys.columns或sys.tables。至于列的顺序位置,它在sys.columns column_id中。@SeanLange我在担任MCT的10年多时间里一直不向学生使用系统表,正如Microsoft官方课件my bad中所述,我没有注意到OP中的sys.columns是目录视图。当然,您是对的,这些也可以使用,并且脚本将在未来的MSSQL版本中兼容,但是在这个问题上,我认为除了名称的长度之外,与信息模式视图相比没有任何优势。在我们的案例中,不需要博客文章中提到的所有详细数据。无论如何,感谢您的链接,非常感谢!:-虽然我很鄙视游标,但它在这里几乎是必需的……而且在那里是嵌套的。啊!!!稍微调整一下,如果表中没有行,就会得到一个被零除的错误+1如果他们使用不推荐的数据类型,那么他们也必须发挥创造性,因为ntext之类的东西对于计数是无效的。根据游标,我也是如此…:再次感谢,好的观点,OP应该定义如何处理没有记录的表。我认为它们是100%填充的,因为不存在的行中有一个空值。另一方面不存在的行包含一个值,因此所有不存在的行都是空的…@SeanLange Yes,Yes,Yes。至少对于ntext等,OP使用了全世界都称之为条件聚合的方法,我认为这也适用于ntext、文本和图像。如果它使用大小写表达式和sum aka条件聚合,则可以避免此问题