不使用 Alter Table 权限截断表

Vyo*_*yom 5 sql-server t-sql alter-table

所以我的 DBA 不希望开发人员授予 Alter table 权限。现在我们创建的过程之一需要截断表(因为显然delete只删除记录,但truncate 也释放了空间)。

现在为了使用 truncate 所需的最低权限是“Alter table”。(来源

但也有一个解决方案描述为“创建一个存储过程,以所有者身份执行仅对一个表或对任何表的存储过程”(由 user3854427 提供)。

我的问题是对他提供的代码的回应。嵌入代码以方便参考:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- =============================================
-- Author:      Yimy Orley Asprilla
-- Create date: Julio 16 de 2014
-- Description: Función para hacer TRUNCATE a una tabla.
-- =============================================
ALTER PROCEDURE [dbo].[spTruncate]
    @nameTable varchar(60)  


WITH EXECUTE AS OWNER
AS

SET NOCOUNT OFF;

DECLARE @QUERY NVARCHAR(200);

SET @QUERY = N'TRUNCATE TABLE ' + @nameTable + ';'


EXECUTE sp_executesql @QUERY;
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 上面的代码是否“代表”所有者创建了一个存储过程?
  2. 谁必须创建此过程(DBA?),因为我绝对无法创建它。
  3. 一旦 DBA 创建此过程,任何成员都可以使用它来截断表,即使他们没有 Alter table 权限?

请帮忙。

Rem*_*anu 8

没有理智的 DBA 会允许这样的过程。这是一个 SQL 注入权限提升向量。我可以传入表名'x; exec sp_myfoo;',瞧。

有基本问题:

  • 表名是NVARCHAR,不是VARCHAR
  • 表名长度为 128,而不是 60
  • sysname 是一个方便的类型来表示对象名称,是一个别名 NVARCHAR(128)
  • 表由架构和名称限定,而不仅仅是名称
  • 构建动态 SQL 的过程必须正确引用名称,使用QUOTENAME

让我们再试一次:

 CREATEPROCEDURE [dbo].[spTruncate]
    @schemaName sysname,
    @tableName sysname
 WITH EXECUTE AS CALLER
 AS
 SET NOCOUNT OFF;
 DECLARE @QUERY NVARCHAR(max);
 SET @QUERY = N'TRUNCATE TABLE ' + QUOTENAME(@schemaName) + '.' + QUOTENAME(@tableName );
 EXECUTE sp_executesql @QUERY;
Run Code Online (Sandbox Code Playgroud)

无需使用 execute 作为 OWNER。由于 CALLER 没问题,只要程序正确签名。请 DBA 按照标准程序签署程序。请参阅SQL Server 中的模块签名签名存储过程。您的 DBA 应该知道如何执行此操作。


sta*_*ray 2

  1. 不,它正在模块当前所有者的上下文中执行 TRUNCATE TABLE。因此,只要存储过程的所有者具有 ALTER TABLE 权限,它就可以工作。
  2. 任何在数据库中拥有 CREATE PROCEDURE 权限以及对在其中创建过程的模式具有 ALTER 权限的人都可以创建该过程。
  3. 任何有权执行模块本身的成员都可以使用它来截断表,即使他们没有 ALTER TABLE 权限。

DELETE 和 TRUNCATE 之间的区别在于 DELETE 记录每行删除,而 TRUNCATE 释放数据页并且仅记录页释放。DELETE 需要对表的 DELETE 权限,而 TRUNCATE 需要 ALTER TABLE。

为了真正将空间释放回操作系统,无论 DELETE 还是 TRUNCATE,都必须执行 SHRINKFILE。