SQL 程序按参数值分组

SQL procedure group by parameter value

我想使用具有动态值的分组功能。

例如:

CREATE PROCEDURE getEmpStats (@COLUMN_NAME VARCHAR(20))
AS
BEGIN
    DECLARE @DUPLICATE_COUNTS INT

    BEGIN
        SELECT @DUPLICATE_COUNTS = SUM(DUP_COUNTS)
        FROM 
            (SELECT COUNT(*) AS DUP_COUNTS
             FROM emp
             GROUP BY @COLUMN_NAME) AS A

        -------------------
    END
END

当我这样编码时,我得到了错误 == >

Each GROUP BY expression must contain at least one column that is not an outer reference.

有什么解决方法吗?

您需要非常小心这种类型的代码,因为它很容易 SQL 注入。

始终在标识符上使用 QUOTENAME。如果列名来自用户代码,则验证它。

因为@DUPLICATE_COUNTS不在动态部分的范围内,需要重新声明为OUTPUT参数。

CREATE PROCEDURE getEmpStats (@COLUMN_NAME varchar(20))
AS

DECLARE @DUPLICATE_COUNTS int;

DECLARE @sql nvarchar(max) = N'

        SELECT @DUPLICATE_COUNTS = SUM(DUP_COUNTS)
        FROM 
            (SELECT COUNT(*) AS DUP_COUNTS
             FROM emp
             GROUP BY ' + QUOTENAME(@COLUMN_NAME) + N') AS A;
';

EXEC sp_executesql @sql, N'@DUPLICATE_COUNTS int OUTPUT', @DUPLICATE_COUNTS = @DUPLICATE_COUNTS

GO

要验证列名,请使用此代码:

IF (NOT EXISTS (SELECT 1
    FROM sys.columns c
    WHERE c.name = @COLUMN_NAME AND c.object_id = OBJECT_ID(N'emp')
    ))
    THROW 50000, 'Non existent column', 0;