如果您使用sp_executesql
. 除非您使该过程在其他人的上下文中执行。而不是选择另一个用户,我宁愿创建一个没有登录的用户。因此,假设您有一个名为 的表dbo.farb
,该用户foobarblat
不能ALTER
(DENY
不是必需的,但它确实证明了这一点):
USE master;
GO
CREATE LOGIN foobarblat WITH PASSWORD = 'foobarblat', CHECK_POLICY = OFF;
GO
USE YourDatabase;
GO
CREATE USER foobarblat FROM LOGIN foobarblat;
GO
CREATE TABLE dbo.farb(id INT);
GO
DENY ALTER ON dbo.farb to foobarblat;
GO
现在让我们创建一个隐藏用户——我们可以给这个用户世界上所有的权限,因为实际上没有人可以作为这个用户登录,但是对于这个例子,我们可以ALTER
在我们的表上授予):
CREATE USER SuperSecret WITHOUT LOGIN;
GO
GRANT ALTER ON dbo.farb TO SuperSecret;
GO
现在我们可以编写一个在SuperSecret
用户上下文中执行的存储过程,但可以通过以下方式执行foobarblat
:
CREATE PROCEDURE dbo.UpdateStats
@tablename NVARCHAR(511)
WITH EXECUTE AS 'SuperSecret'
AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'UPDATE STATISTICS ' + @tablename;
EXEC sp_executesql @sql;
END
GO
GRANT EXEC ON dbo.UpdateStats TO foobarblat;
现在在一个新窗口中使用foobarblat
- 你应该能够执行这个没问题:
EXEC dbo.UpdateStats 'dbo.farb';