没有 ALTER 权限的 UPDATE 权限

UPDATE PERMISSION without ALTER permission

提问人:Json 提问时间:8/16/2019 最后编辑:Thom AJson 更新时间:8/16/2019 访问量:267

问:

我有一个存储过程,它将一些数据插入到表中。最后,我想更新该表的统计信息。执行该过程的用户没有足够的权限来运行 UPDATE STATITICS。现在,我的想法是创建一个存储过程,该存储过程以所有者身份执行(具有足够的权限),并授予用户对此存储过程的执行权限。 到目前为止,它有效,但是如果我使用

EXEC dwh.sp_UpdateStatistics @schemaName = 'dwh', @tableName = 'dim_Assets;SELECT 123;'

它返回 123。

我已经阅读了有关SQL注入的文章,但是我无法弄清楚如何解决这个问题。

程序如下:

CREATE PROCEDURE dwh.sp_UpdateStatistics @schemaName VARCHAR(10) = NULL, @tableName VARCHAR(50) = NULL
WITH EXECUTE AS owner
AS

DECLARE @updateStatistics NVARCHAR(MAX);

SET @updateStatistics = N'UPDATE STATISTICS ' + @schemaName + '.' + @tableName;

EXEC sp_executesql @updateStatistics;

您能否帮助我找到一种方法,在不授予更多权限且没有SQL注入风险的情况下更新统计信息。(并不是说他们意料之中,而是完全在内部,而只是为了睡个好觉和“以正确的方式做”的感觉) 谢谢! (我有 SQLServer2017,但我无法创建带有此标签的帖子。

sql-server stored-procedures 权限 sql-injection

评论

1赞 Sean Lange 8/16/2019
略微绕道而行,但应避免使用sp_前缀。它保留用于 MS 程序。要么选择不同的前缀,要么最好完全没有前缀。sqlperformance.com/2012/10/t-sql-queries/sp_prefix
0赞 Json 8/17/2019
谢谢你的信息!没有意识到这一点,我会相应地改变它。实际上,我从没想过这会产生影响。

答:

1赞 Thom A 8/16/2019 #1

用。我还建议对动态对象使用适当的数据类型:QUOTENAME

CREATE PROCEDURE dwh.sp_UpdateStatistics @schemaName sysname, @tableName sysname
WITH EXECUTE AS owner
AS BEGIN

    DECLARE @updateStatistics NVARCHAR(MAX);

    SET @updateStatistics = N'UPDATE STATISTICS ' + QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + N';';

    EXEC sp_executesql @updateStatistics;
END;

我还从参数中删除了,因为将它们设置为可选是没有意义的(因为 的值将是 )。= NULL@updateStatisticsNULL

如果你想使代码在对象不存在时不会运行,请使用如下方法进行检查:INFORMATION_SCHEMA

CREATE PROCEDURE dwh.sp_UpdateStatistics @schemaName sysname, @tableName sysname
WITH EXECUTE AS owner
AS BEGIN

    DECLARE @updateStatistics NVARCHAR(MAX);

    SELECT @updateStatistics = N'UPDATE STATISTICS ' + QUOTENAME(T.TABLE_SCHEMA) + N'.' + QUOTENAME(T.TABLE_NAME) + N';'
    FROM INFORMATION_SCHEMA.TABLES T
    WHERE T.TABLE_SCHEMA = @schemaName
      AND T.TABLE_NAME = @tableName;

    EXEC sp_executesql @updateStatistics;
END;

如果对象不存在,则将导致值为 ,然后不会运行(动态)SQL。@updateStatisticsNULL

评论

0赞 SMor 8/17/2019
让我们补充一点 - 绝对没有理由将局部变量定义为 nvarchar(max)。
0赞 Json 8/19/2019
为什么?是的,我可以使用一个数字,因为变量是架构和表名,但至少对于存储空间,我认为它不会有任何区别,因为 varchar(max) 只占用它需要的空间。
0赞 Json 10/29/2019
有关@SMor的 nvarchar(max) 评论的更多信息,我找到了这个链接: varchar(max) 无处不在?
0赞 Thom A 10/29/2019
这与列有关,@Json,而不是变量。