I am trying to built generic query to pass column name I want to count on and table name I want to select value.
So far this is my code:
ALTER PROCEDURE [dbo].[GenericCountAll]
@TableName VARCHAR(100),
@ColunName VARCHAR(100)
AS
BEGIN
DECLARE @table VARCHAR(30);
DECLARE @Rowcount INT;
SET @table = N'SELECT COUNT(' + @ColunName +') FROM ' + @TableName + '';
EXEC(@table)
SET @Rowcount = @@ROWCOUNT
SELECT @Rowcount
END
Trying to execute like this:
EXEC GenericCountAll 'T_User', 'Id';
but looks like I get two results, first result always returning a value of 1, and the second result returns the real count. Can anyone take a look?
Don't create dynamic sql like that! Imagine if I ran:
EXEC GenericCountAll '*/DROP PROCEDURE dboGenericCountAll;--', '1);/*';
The resulting executed SQL would be:
SELECT COUNT(1);/*) FROM */ DROP PROCEDURE dboGenericCountAll;--
That would, quite simply, DROP
your procedure. And that's just a simple example. If i knew I could keep doing malicious things, I might even be able to create a new login or user, and make the a db_owner
or sysadmin
(depending on the permissions of what ever is being used to run that procedure).
I don't know what the point of the @@ROWCOUNT
is either, I doubt that's needed. Thus, to make this SAFE you would need to do something like this:
ALTER procedure [dbo].[GenericCountAll]
@TableName sysname, --Note the datatype change
@ColumnName sysname
AS
BEGIN
DECLARE @SQL nvarchar(MAX);
SELECT N'SELECT COUNT(' + QUOTENAME(c.[name]) + N') AS RowCount' + NCHAR(10) +
N'FROM ' + QUOTENAME(s.[name]) + N'.' + QUOTENAME(t.name) + N';'
FROM sys.tables t
JOIN sys.schemas s ON t.schema_id = s.schema_id
JOIN sys.columns c ON t.object_id = c.object_id
WHERE t.[name] = @TableName
AND c.[name] = @ColumnName;
/*
If either the column or the table doesn't exist, then @SQL
will have a value of NULL. This is a good thing, as it
is a great way to further avoid injection, if a bogus
table or column name is passed
*/
IF @SQL IS NOT NULL BEGIN;
PRINT @SQL; --Your best debugging friend
EXEC sp_executesql @SQL;
END ELSE BEGIN;
RAISERROR(N'Table does not exist, or the Column does not exist for the Table provided.',11,1);
END;
END
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.