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;
我想使用具有动态值的分组功能。
例如:
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;