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)
我的问题是:
请帮忙。
没有理智的 DBA 会允许这样的过程。这是一个 SQL 注入权限提升向量。我可以传入表名'x; exec sp_myfoo;',瞧。
有基本问题:
NVARCHAR,不是VARCHARsysname 是一个方便的类型来表示对象名称,是一个别名 NVARCHAR(128)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 应该知道如何执行此操作。
DELETE 和 TRUNCATE 之间的区别在于 DELETE 记录每行删除,而 TRUNCATE 释放数据页并且仅记录页释放。DELETE 需要对表的 DELETE 权限,而 TRUNCATE 需要 ALTER TABLE。
为了真正将空间释放回操作系统,无论 DELETE 还是 TRUNCATE,都必须执行 SHRINKFILE。