Создание цикла столбца в цикле таблицы для расчета скорости заполнения для всех полей в базе данных - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть 2 базы данных с более чем 400 таблицами, для которых я должен рассчитать уровень заполнения.У меня есть цикл для расчета скорости заполнения для всех столбцов в таблице, но как я могу сделать это для всех таблиц в базе данных?Пожалуйста помоги!Я использую SQL Server.

Вот код для циклического перебора всех столбцов в таблице для расчета скорости заполнения -

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

1 Ответ

0 голосов
/ 06 сентября 2018

Я предлагаю использовать курсор для этой небольшой задачи:

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;
...