SQL Server - Dynamic PIVOT Table - SQL Injection

前端 未结 3 1406
攒了一身酷
攒了一身酷 2020-11-27 18:54

Sorry for the long question but this contains all the SQL I\'ve used to test the scenario to hopefully make it clear as to what I\'m doing.

I\'m build up some dynami

3条回答
  •  悲哀的现实
    2020-11-27 19:02

    A bit of refactoring...

    CREATE PROCEDURE ExecutePivot (
        @TableName sysname,
        @GroupingColumnName sysname,
        @AggregateExpression VARCHAR(256),
        @SelectExpression VARCHAR(256),
        @TotalColumnName VARCHAR(256) = 'Total',
        @DefaultNullValue VARCHAR(256) = NULL,
        @IsExec BIT = 1)
    AS
    BEGIN
        DECLARE @DistinctGroupedColumnsQuery VARCHAR(MAX);
        SELECT @DistinctGroupedColumnsQuery = CONCAT('SELECT DISTINCT ',@GroupingColumnName,' FROM ',@TableName,';');
        DECLARE @DistinctGroupedColumnsResult TABLE ( [row] VARCHAR(MAX) );
        INSERT INTO @DistinctGroupedColumnsResult EXEC(@DistinctGroupedColumnsQuery);
    
        DECLARE @GroupedColumns VARCHAR(MAX);
        SELECT @GroupedColumns = STUFF ( ( SELECT DISTINCT CONCAT(', ',QUOTENAME([row])) FROM @DistinctGroupedColumnsResult FOR XML PATH('') ), 1, 1, '' );
    
        DECLARE @GroupedColumnsNullReplaced VARCHAR(MAX);
        IF(@DefaultNullValue IS NOT NULL)
            SELECT @GroupedColumnsNullReplaced = STUFF ( ( SELECT DISTINCT CONCAT(', ISNULL(',QUOTENAME([row]),',',@DefaultNullValue,') AS ',QUOTENAME([row])) FROM @DistinctGroupedColumnsResult FOR XML PATH('') ), 1, 1, '' );
        ELSE
            SELECT @GroupedColumnsNullReplaced=@GroupedColumns;
    
        DECLARE @ResultExpr VARCHAR(MAX) = CONCAT('
            ; WITH cte AS
            (
                SELECT ',@SelectExpression,', ',@GroupedColumns,'
                FROM ',@TableName,'
                PIVOT ( ',@AggregateExpression,' FOR ',@GroupingColumnName,' IN (',@GroupedColumns,') ) as p
            )
            , cte2 AS
            (
                SELECT ',@SelectExpression,', ',@GroupedColumnsNullReplaced,'
                FROM cte
            )
            SELECT ',@SelectExpression,', ',REPLACE(@GroupedColumns,',','+'),' AS ',@TotalColumnName,', ',@GroupedColumns,'
            FROM cte2;
            ');
    
        IF(@IsExec = 1) EXEC(@ResultExpr);
        ELSE SELECT @ResultExpr;
    END;
    

    Usage example:

    select schema_id, type_desc, 1 as Item 
        into PivotTest
    from sys.objects;
    
    EXEC ExecutePivot 'PivotTest','type_desc','SUM(Item)','schema_id','[Total Items]','0',1;
    

提交回复
热议问题