0

ここに画像の説明を入力

以下に、NULL レコードの数、列の MinValue、MaxValue および AvgValue のレコードを返すクエリがあります。ただし、クエリは実行されますが、レコードは返されず、列ヘッダーだけが返されます。コードを修正して、どこが間違っているかを示すことはできますか? 計算フィールドは、以下のクエリで定義されているように、数値、浮動小数点数、小数、およびその他の選択されたデータ型にのみ適用する必要があります。

DECLARE @schemaName AS sysname;
    DECLARE @tableName AS sysname;
    DECLARE @columnName AS sysname;
    DECLARE @schema_id AS int;
    DECLARE @object_id AS int;
    DECLARE @column_id AS int;
    DECLARE @isNullable AS bit;
    DECLARE @lastSchema_id AS int;
    DECLARE @lastTable_id AS int;
    DECLARE @recordCount AS bigint;
    DECLARE @MinValue As int;
    DECLARE @MaxValue As int;
    DECLARE @AvgValue As int;
    DECLARE @nullCnt AS bigint;
    DECLARE @SQL as nvarchar(max);
    DECLARE @paramDefinition NVARCHAR(max);

    if exists(select name from tempdb..sysobjects where name LIKE'#Columns%')
    DROP TABLE #Columns;

    CREATE TABLE #Columns (
        schema_id int,
        object_id int,
        column_id int,
        schemaName sysname,
        tableName sysname,
        columnName sysname,
        recordCnt bigint,
        MinValue int,
        MaxValue int,
        AvgValue int,
        nullCnt bigint,
        nullPct numeric(38,35) );

    -- Set to the @lastSchema_id and @lastTable_id to NULL so that the first 
    --  loop through the cursor the record count is generated.
    SET @lastSchema_id = NULL;
    SET @lastTable_id = NULL;

    -- List of all the user schemas.tables.columns
    --  in the database
    DECLARE c_Cursor CURSOR FOR
    SELECT schemas.schema_id
         , all_objects.object_id
         , all_columns.column_id
         , schemas.name AS schemaName
         , all_objects.name AS tableName
         , all_columns.name AS columnName
         , all_columns.is_nullable
      FROM sys.schemas
     INNER JOIN sys.all_objects
        ON schemas.schema_id = all_objects.schema_id
       AND all_objects.type = 'U'
     INNER JOIN sys.all_columns
        ON all_objects.object_id = all_columns.object_id
         WHERE all_objects.type LIKE '%int%'
         OR all_objects.type LIKE '%float%' 
         OR all_objects.type LIKE '%decimal%'
         OR all_objects.type LIKE '%numeric%'
         OR all_objects.type LIKE '%real%'
         OR all_objects.type LIKE '%money%'
     ORDER BY schemas.schema_id
         , all_objects.object_id
         , all_columns.column_id;

    OPEN c_Cursor;

    FETCH NEXT FROM c_Cursor
     INTO @schema_id
        , @object_id
        , @column_id
        , @schemaName
        , @tableName
        , @columnName
        , @isNullable;

    -- Loop through the cursor
    WHILE @@FETCH_STATUS = 0
    BEGIN

        -- Get the record count for the table we are currently working on if this is
        --  the first time we are encountering the table.
        IF ( ( @schema_id <> @lastSchema_id ) OR ( @object_id <> @lastTable_id )
          OR ( @lastSchema_id IS NULL ) OR ( @lastTable_id IS NULL ) )
        BEGIN

            SET @SQL = N'SELECT @recordCount = COUNT(1) FROM ' + QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + ';';
            SET @paramDefinition = N'@recordCount bigint OUTPUT';

            exec sp_executesql @SQL,
                               @paramDefinition,
                               @recordCount = @recordCount OUTPUT;

        END

        -- Get the min value for the table 

    IF ( ( @schema_id <> @lastSchema_id ) OR ( @object_id <> @lastTable_id )
          OR ( @lastSchema_id IS NULL ) OR ( @lastTable_id IS NULL ) )
        BEGIN

            SET @SQL = N'SELECT @MinValue = COUNT(1) FROM ' + QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + ';';
            SET @paramDefinition = N'@MinValue int OUTPUT';

            exec sp_executesql @SQL,
                               @paramDefinition,
                               @MinValue = @MinValue OUTPUT;

        END

        --Get the max value for the table

        IF ( ( @schema_id <> @lastSchema_id ) OR ( @object_id <> @lastTable_id )
          OR ( @lastSchema_id IS NULL ) OR ( @lastTable_id IS NULL ) )
        BEGIN

            SET @SQL = N'SELECT @MaxValue = COUNT(1) FROM ' + QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + ';';
            SET @paramDefinition = N'@MaxValue int OUTPUT';

            exec sp_executesql @SQL,
                               @paramDefinition,
                               @MaxValue = @MaxValue OUTPUT;

        END

        --Get the avg value for the table
    IF ( ( @schema_id <> @lastSchema_id ) OR ( @object_id <> @lastTable_id )
          OR ( @lastSchema_id IS NULL ) OR ( @lastTable_id IS NULL ) )
        BEGIN

            SET @SQL = N'SELECT @AvgValue = COUNT(1) FROM ' + QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + ';';
            SET @paramDefinition = N'@AvgValue int OUTPUT';

            exec sp_executesql @SQL,
                               @paramDefinition,
                               @AvgValue = @AvgValue OUTPUT;

        END



        -- If the column is NOT NULL, there is no reason to do a count
        --  Set the nullCnt and nullPct to 0
        IF ( @isNullable = 0 )
        BEGIN


            INSERT INTO #Columns
                 ( [schema_id]
                 , [object_id]
                 , column_id
                 , schemaName
                 , tableName
                 , columnName
                 , recordCnt
                 , nullCnt
                 , nullPct )
            VALUES
                 ( @schema_id
                 , @object_id
                 , @column_id
                 , @schemaName
                 , @tableName
                 , @columnName
                 , @recordCount
                 , 0
                 , 0.0 );
        END
        -- If the column is NULL, count the number of NULL fields in the table.
        ELSE
        BEGIN

            SET @SQL = N'SELECT @nullCnt = COUNT(1) FROM ' + QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + 
                       N' WHERE ' + QUOTENAME(@columnName) + N' IS NULL;';
            SET @paramDefinition = N'@nullCnt bigint OUTPUT';

            PRINT @SQL;

            exec sp_executesql @SQL,
                               @paramDefinition,
                               @nullCnt = @nullCnt OUTPUT;

            INSERT INTO #Columns
                 ( [schema_id]
                 , [object_id]
                 , column_id
                 , schemaName
                 , tableName
                 , columnName
                 , recordCnt
                 , nullCnt
                 , nullPct )
            VALUES
                 ( @schema_id
                 , @object_id
                 , @column_id
                 , @schemaName
                 , @tableName
                 , @columnName
                 , @recordCount
                 , @nullCnt
                 -- USE NULLIF in case there are no recods in the table
                 , ISNULL( @nullCnt * 1.0 / NULLIF( @recordCount, 0) * 100.0, 0 ) );

        END

        -- Set the @lastSchema_id and @lastTable_id so that on 
        --  the next loop, if it's the same table there is no 
        --  need to recount the columns for the table.
        SET @lastSchema_id = @schema_id;
        SET @lastTable_id = @object_id;

        FETCH NEXT FROM c_Cursor
         INTO @schema_id
            , @object_id
            , @column_id
            , @schemaName
            , @tableName
            , @columnName
            , @isNullable;

    END;

    CLOSE c_Cursor;
    DEALLOCATE c_Cursor;

    SELECT *
      FROM #Columns;
4

1 に答える 1