南卡罗来纳州 内部联接信息\u schema.tables作为t 关于c.table\u name=t.table\u name 哪里 t、 表\u type='base table'和 t、 table_name=@tablename 设置@sql=left(@sql,len(@sql)-10) --打印@sql exec(@sql) 结束

南卡罗来纳州 内部联接信息\u schema.tables作为t 关于c.table\u name=t.table\u name 哪里 t、 表\u type='base table'和 t、 table_name=@tablename 设置@sql=left(@sql,len(@sql)-10) --打印@sql exec(@sql) 结束,sql,sql-server,tsql,Sql,Sql Server,Tsql,你可以在这篇博文中找到更多细节挑战: 下面这样的模式更改使我们的填充率方法比实际的方法稍微困难一些 表名更改 列名更改 数据类型更改 删除现有列 添加新列 由于上述挑战,我们不能简单地使用静态解决方案来查找表的填充率。相反,我们需要一些类似动态的方法来避免我们未来的重复工作 先决条件: 在下面的示例中,我们将使用一个名为“Get_FillRate”的存储过程进行演示。如果数据库中有任何对象名称相同,请确保更改以下存储过程名称 使用数据加载脚本创建示例表 临时表-#测试计划 在表动

你可以在这篇博文中找到更多细节

挑战:

下面这样的模式更改使我们的填充率方法比实际的方法稍微困难一些

  • 表名更改

  • 列名更改

  • 数据类型更改

  • 删除现有列

  • 添加新列

由于上述挑战,我们不能简单地使用静态解决方案来查找表的填充率。相反,我们需要一些类似动态的方法来避免我们未来的重复工作

先决条件:

在下面的示例中,我们将使用一个名为“Get_FillRate”的存储过程进行演示。如果数据库中有任何对象名称相同,请确保更改以下存储过程名称

使用数据加载脚本创建示例表

临时表-#测试计划

在表动态方法中查找填充率的SQL过程 输入参数

这两个输入参数都是必需的

  • @p_TableName-用于此输入参数的数据类型为NVARCHAR(128),可空性不为NULL

  • @p_Include_BlankAsNotFilled-用于此输入参数的数据类型为BIT,可空性不为NULL,需要给出0或1。默认情况下,0表示关闭。1打开(当作为1给出时-空白条目将被视为未填充数据)

  • 输出列

    有两个输出列。这两个列都是不可为空的输出列

  • [列名]-此输出列使用的数据类型为sysname,可空性不为NULL。用户给定表名的所有列名都将作为行值

  • [填充率(%)]-此输出列使用的数据类型为十进制(5,2),可空性不为空。从0.00到100.00的值将以各自的列名作为结果

  • Info reg存储过程

    • 创建了名为“Get_FillRate”的存储过程
    • 要避免返回的行数,请将NOCOUNT设置为ON
    • 尝试,为错误处理添加捕获块
    • 要读取未提交的修改,请将事务隔离级别设置为read Uncommitted
    • 还包括参数嗅探概念
    • 对表名输入参数进行了一些处理,以支持用户键入表名格式,如“.Table_Name”、“Table_Name”、“Table_Name”、“Table_Name”、“Table_Name”、“dbo.Table_Name”、“dbo.[Table_Name]”、“[dbo].[Table_Name]”等
    • 验证包括在开始时,当用户给出的不是“表名”时,存储过程将抛出“此数据库中不存在表”作为错误消息
    • 存储过程中使用名为SYS.OBJECTS和SYS.COLUMNS的系统表以及名为INFORMATION_SCHEMA.COLUMNS的系统视图
    • 使用INFORMATION_SCHEMA.COLUMNS中的ORDINAL_POSITION返回结果集,其列顺序与表结构中已有的列顺序相同
    • CudioNo.NealNo.Studio。使用列来支持诸如空白的条件,无论是否需要考虑,如未填写的条目。
    • 使用INFORMATION_SCHEMA.COLUMNS中的COLUMN_NAME来显示具有相应填充率的最终结果集
    • 使用动态查询来支持动态方法,这将避免静态解决方案(如模式更改)带来的所有挑战
    • 方法1(带WHILE循环的动态查询)和方法2(带UNION ALL的动态查询)都会生成相同的结果集,并具有相同的功能,其中一些指标(如CPU时间、运行时间、逻辑读取)在方法2中更好
    方法1-使用WHILE循环

    如果需要将空值和空/空值都考虑为未填充

    ,则执行如下所示
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=0;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=1;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=0;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=1;
    
    方法1-输出

    方法2-使用UNION ALL

    如果需要将空值和空/空值都考虑为未填充

    ,则执行如下所示
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=0;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=1;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=0;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=1;
    
    方法2-输出

    方法1与方法2之间的度量差异

    为了了解方法1和方法2之间的差异,需要考虑以下四个指标

    • Exec查询计划中的查询集数
    • 总CPU时间(毫秒)
    • 总运行时间(毫秒)
    • 总逻辑读取数


    总之,我们已经了解了如何使用T-SQL查询查找表的填充率,该查询适用于在AZURE和本地SQL数据库中运行。因此,它将有助于我们立即有效地做出业务决策。

    挑战:

    下面这样的模式更改使我们的填充率方法比实际的方法稍微困难一些

    • 表名更改

    • 列名更改

    • 数据类型更改

    • 删除现有列

    • 添加新列

    由于上述挑战,我们不能简单地使用静态解决方案来查找表的填充率。相反,我们需要一些类似动态的方法来避免我们未来的重复工作

    先决条件:

    在下面的示例中,我们将使用一个名为“Get_FillRate”的存储过程进行演示。如果数据库中有任何对象名称相同,请确保更改以下存储过程名称

    使用数据加载脚本创建示例表

    临时表-#测试计划

    在表动态方法中查找填充率的SQL过程 输入参数

    两个都是t
    --dropping temp table if exists
    IF OBJECT_ID('TempDb..#TestEmp') IS NOT NULL
        DROP TABLE #TestEmp;
      
    CREATE TABLE #TestEmp
    (
        [TestEmp_Key] INT IDENTITY(1,1) NOT NULL,
        [EmpName] VARCHAR(100) NOT NULL,
        [Age] INT NULL,
        [Address] VARCHAR(100) NULL,
        [PhoneNo] VARCHAR(11) NULL,
        [Inserted_dte] DATETIME NOT NULL,
        [Updated_dte] DATETIME NULL,
     CONSTRAINT [PK_TestEmp] PRIMARY KEY CLUSTERED
     (
        TestEmp_Key ASC
     )
    );
    GO
       
    INSERT INTO #TestEmp
    (EmpName,Age,[Address],PhoneNo,Inserted_dte)
    VALUES
    ('Arul',24,'xxxyyy','1234567890',GETDATE()),
    ('Gokul',22,'zzzyyy',NULL,GETDATE()),
    ('Krishna',24,'aaa','',GETDATE()),
    ('Adarsh',25,'bbb','1234567890',GETDATE()),
    ('Mani',21,'',NULL,GETDATE()),
    ('Alveena',20,'ddd',NULL,GETDATE()),
    ('Janani',30,'eee','',GETDATE()),
    ('Vino',26,NULL,'1234567890',GETDATE()),
    ('Madhi',25,'ggg',NULL,GETDATE()),
    ('Ronen',25,'ooo',NULL,GETDATE()),
    ('Visakh',25,'www',NULL,GETDATE()),
    ('Jayendran',NULL,NULL,NULL,GETDATE());
    GO
       
    SELECT [TestEmp_Key],[EmpName],[Age],[Address],[PhoneNo],[Inserted_dte],[Updated_dte] FROM #TestEmp;
    GO
    
    CREATE OR ALTER PROCEDURE [dbo].[Get_FillRate]  
    (
        @p_TableName                  NVARCHAR(128),
        @p_Include_BlankAsNotFilled   BIT = 0 -- 0-OFF(Default); 1-ON(Blank As Not Filled Data)
    )
    AS
    BEGIN
      
    BEGIN TRY
       
    SET NOCOUNT ON;
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
      
    --Parameter Sniffing
    DECLARE @TableName                  NVARCHAR(128),
            @Include_BlankAsNotFilled   BIT,
            @ColumnName                 NVARCHAR(128),
            @R_NO                       INT,
            @DataType_Field             BIT,
            @i                          INT, --Iteration
            @RESULT                     NVARCHAR(MAX);
      
    SELECT  @TableName                  =   @p_TableName,
            @Include_BlankAsNotFilled   =   @p_Include_BlankAsNotFilled,
            @i                          =   1;
              
    --To Support some of the table formats that user typing.
    SELECT @TableName   =REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@TableName,'[',''),']',''),'dbo.',''),'...',''),'..',''),'.','');       
       
    --validation
    IF NOT EXISTS(SELECT 1 FROM SYS.OBJECTS WHERE [TYPE]='U' AND [NAME]=@TableName )   
        BEGIN
            SELECT Result = 1 , Reason ='Table not exists in this Database' ;
            RETURN 1;
        END;
       
    --dropping temp table if exists - for debugging purpose
    IF OBJECT_ID('TempDb..#Temp') IS NOT NULL
        DROP TABLE #Temp;
    IF OBJECT_ID('TempDb..#Columns') IS NOT NULL
        DROP TABLE #Columns;
      
    --temp table creations
    CREATE TABLE #Temp
    (
    [R_NO] INT NOT NULL,
    [ColumnName] NVARCHAR(128) NOT NULL,
    [FillRate] DECIMAL(5,2) NOT NULL
    PRIMARY KEY CLUSTERED (ColumnName)
    );
      
    CREATE TABLE #Columns
    (
    [R_NO] INT NOT NULL,
    [Name] [sysname] NOT NULL,
    [DataType_Field] BIT NOT NULL
    PRIMARY KEY CLUSTERED ([Name])
    );
       
    INSERT INTO #Columns ([R_NO],[Name],[DataType_Field])
    SELECT
        COLUMN_ID,
        [Name],
        IIF(collation_name IS NULL,0,1)
    FROM SYS.COLUMNS WHERE OBJECT_ID = OBJECT_ID(@TableName);
       
    WHILE @i <= ( SELECT MAX(R_NO) FROM #Columns) --Checking of Iteration till total number of columns
        BEGIN
            SELECT @DataType_Field=DataType_Field,@ColumnName=[Name],@R_NO=[R_NO] FROM #Columns WHERE R_NO = @i;
       
              SET @RESULT =
                'INSERT INTO #Temp ([R_NO],[ColumnName], [FillRate]) ' +
                'SELECT ' + QUOTENAME(@R_NO,CHAR(39)) + ',
                    ''' + @ColumnName + ''',
                    CAST((100*(SUM(
                        CASE WHEN ' +
                            CASE
                                WHEN @Include_BlankAsNotFilled = 0
                                  THEN '[' + @ColumnName + '] IS NOT NULL'
                                WHEN @DataType_Field = 0
                                  THEN '[' + @ColumnName + '] IS NOT NULL'
                                ELSE 'ISNULL([' + @ColumnName + '],'''')<>'''' ' END +
                        ' THEN 1 ELSE 0 END)*1.0 / COUNT(*)))
                    AS DECIMAL(5,2))
                FROM ' + @TableName;
       
            --PRINT(@RESULT); --for debug purpose
            EXEC(@RESULT);
       
            SET @i += 1; -- Incrementing Iteration Count
        END;
       
     --Final Result Set
        SELECT
          ColumnName AS [Column Name],
          FillRate AS [Fill Rate (%)]
        FROM #TEMP
        ORDER BY [R_NO];
       
        RETURN 0;
      
    END TRY
    BEGIN CATCH  --error handling even it is fetching stored procedure
        SELECT
             ERROR_NUMBER()     AS ErrorNumber
            ,ERROR_SEVERITY()   AS ErrorSeverity
            ,ERROR_STATE()      AS ErrorState
            ,ERROR_PROCEDURE()  AS ErrorProcedure
            ,ERROR_LINE()       AS ErrorLine
            ,ERROR_MESSAGE()    AS ErrorMessage;
        RETURN 1;
    END CATCH;
      
    END;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=0;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=1;
    
    CREATE OR ALTER PROCEDURE [dbo].[Get_FillRate]  
    (
        @p_TableName                  NVARCHAR(128),
        @p_Include_BlankAsNotFilled   BIT = 0 -- 0-OFF(Default); 1-ON(Blank As Not Filled Data)
    )
    AS
    BEGIN
      
    BEGIN TRY
       
    SET NOCOUNT ON;
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
      
    --Parameter Sniffing
    DECLARE @TableName                  NVARCHAR(128),
            @Include_BlankAsNotFilled   BIT,
            @RESULT                     NVARCHAR(MAX);
      
    SELECT  @TableName                  =   @p_TableName,
            @Include_BlankAsNotFilled   =   @p_Include_BlankAsNotFilled,
            @RESULT                     =   '';
              
    --To Support some of the table formats that user typing.
    SELECT @TableName   =REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@TableName,'[',''),']',''),'dbo.',''),'...',''),'..',''),'.','');               
       
    --validation
    IF NOT EXISTS(SELECT 1 FROM SYS.OBJECTS WHERE [TYPE]='U' AND [NAME]=@TableName )   
        BEGIN
            SELECT Result = 1 , Reason ='Table not exists in this Database' ;
            RETURN 1;
        END;
      
    --dropping temp table if exists - for debugging purpose
    IF OBJECT_ID('TempDb..#Columns') IS NOT NULL
        DROP TABLE #Columns;
          
    --temp table creations
    CREATE TABLE #Columns
    (
    [ORDINAL_POSITION] INT NOT NULL,
    [COLUMN_NAME] [sysname] NOT NULL,
    [DataType_Field] BIT NOT NULL,
    [TABLE_NAME] [sysname] NOT NULL
    PRIMARY KEY CLUSTERED ([ORDINAL_POSITION],[COLUMN_NAME])
    );
      
    INSERT INTO #Columns ([ORDINAL_POSITION],[COLUMN_NAME],[DataType_Field],[TABLE_NAME])
    SELECT
        [ORDINAL_POSITION],
        [COLUMN_NAME],
        CASE WHEN COLLATION_NAME IS NOT NULL THEN 1 ELSE 0 END,
        [TABLE_NAME]
    FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =@tablename; --Using System_View
       
    --Final Result Set
    SELECT @RESULT = @RESULT+ N'SELECT '''+C.COLUMN_NAME+''' AS [Column Name],
                                CAST((100*(SUM(
                                        CASE WHEN ' +
                                            CASE
                                                WHEN @include_blankasnotfilled = 0
                                                  THEN '[' + C.COLUMN_NAME + '] IS NOT NULL'
                                                WHEN C.[DataType_Field]=0
                                                  THEN '[' + C.COLUMN_NAME + '] IS NOT NULL'
                                                ELSE 'ISNULL([' + C.COLUMN_NAME + '],'''')<>'''' ' END +
                                        ' THEN 1 ELSE 0 END)*1.0 / COUNT(*)))
                                AS DECIMAL(5,2)) AS [Fill Rate (%)]
                            FROM '+C.TABLE_NAME+' UNION ALL '
    FROM #Columns C;
      
    SET @RESULT=LEFT(@RESULT,LEN(@RESULT)-10); --To Omit 'Last UNION ALL '.
      
    --PRINT(@RESULT); --for debug purpose
    EXEC(@RESULT);
       
        RETURN 0;
      
    END TRY
    BEGIN CATCH  --error handling even it is fetching stored procedure
        SELECT
             ERROR_NUMBER()     AS ErrorNumber
            ,ERROR_SEVERITY()   AS ErrorSeverity
            ,ERROR_STATE()      AS ErrorState
            ,ERROR_PROCEDURE()  AS ErrorProcedure
            ,ERROR_LINE()       AS ErrorLine
            ,ERROR_MESSAGE()    AS ErrorMessage;
        RETURN 1;
    END CATCH;
      
    END;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=0;
    
    EXEC [Get_FillRate] @p_TableName='#TestEmp',@p_Include_BlankAsNotFilled=1;