Quais permissões são necessárias para truncar uma tabela?

14

Eu tenho uma conta SQL com as seguintes permissões em um banco de dados:

insira a descrição da imagem aqui

A db_executorfunção da qual você vê essa conta como membro foi criada por este script:

CREATE ROLE [db_executor] AUTHORIZATION [dbo]
GO

GRANT EXECUTE TO [db_executor] 
GO

Quando eu executar um select, update, insertou deletesobre a mesa, ele funciona bem. Quando tento truncatea tabela, essa mensagem de erro é exibida:

Não foi possível encontrar o objeto "TableName" porque ele não existe ou você não tem permissões.

Que permissão está faltando nesta conta?

Mansfield
fonte
TRUNCATE TABLEé DDL, não DML.
usar o seguinte código

Respostas:

26

O melhor lugar para procurar essas informações é nos livros on-line. O artigo TRUNCATE TABLE aqui indica:

A permissão mínima necessária é ALTER em table_name. As permissões TRUNCATE TABLE são padrão para o proprietário da tabela, membros da função de servidor fixa sysadmin e as funções de banco de dados fixas db_owner e db_ddladmin e não são transferíveis. No entanto, você pode incorporar a instrução TRUNCATE TABLE em um módulo, como um procedimento armazenado, e conceder permissões apropriadas ao módulo usando a cláusula EXECUTE AS.

Portanto, ALTER são as permissões mínimas necessárias. Você pode obtê-lo como proprietário do banco de dados, como DB_DDLAdmin. Ou apenas conceda alteração.

Se você pensar sobre o que o truncado faz e como ele funciona, isso faz sentido, é um comando bastante "severo" e esvazia a tabela de dados e o faz rapidamente.

Mike Walsh
fonte
12

Conforme esta referência na BOL :

A permissão mínima necessária é ALTER em table_name . As permissões TRUNCATE TABLE são padrão para o proprietário da tabela , membros da função de servidor fixa sysadmin e as funções de banco de dados fixas db_owner e db_ddladmin e não são transferíveis. No entanto, você pode incorporar a instrução TRUNCATE TABLE em um módulo, como um procedimento armazenado, e conceder permissões apropriadas ao módulo usando a cláusula EXECUTE AS.

Thomas Stringer
fonte
3

Você pode criar um procedimento armazenado com executar como proprietário em apenas uma tabela ou um procedimento armazenado em qualquer tabela. No próximo código, é armazenado o procedimento para truncar qualquer tabela sem garantir a permissão de db_ownerou de outra:

USE [database name]
GO

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;
user3854427
fonte
Esta é uma boa ideia, mas poderia ser melhorada. por exemplo, adicionando try..catch, outra coisa é verificar se há restrições, especialmente chaves estrangeiras, também campos de identidade, que precisam ser reenviadas. você pode ter tudo isso no seu procedimento. se você fizer isso, compartilhe o novo código. ;)
Marcello Miorelli
1

Você pode criar um procedimento armazenado com executar como proprietário em apenas uma tabela ou um procedimento armazenado em qualquer tabela. No próximo código, é armazenado o procedimento para truncar qualquer tabela sem garantir a permissão do db_owner ou de outro. Nesta versão do SP está incluído tratamento de erros e prevenção de injeção de SQL

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


/****** Se validan el parametro de entrada @strTabla para evitar un SQL inyección, Yimy Asprilla ******/
CREATE PROCEDURE [dbo].[spTruncate] 
        @strTabla VARCHAR(50)
WITH EXECUTE AS OWNER
AS
-- =============================================
 -- Author:  Yimy Asprilla
 -- Create date: Julio 16 de 2014
 -- Update: September 21 2017
 -- Description: Función para hacer TRUNCATE a una tabla si ser owner de la tabla. con manejo de errores y SQL Inyection
 -- =============================================
SET NOCOUNT ON

DECLARE @strSQL VARCHAR(500);
DECLARE @object_id int;

SET @object_id = OBJECT_ID(@strTabla);

BEGIN TRY
    IF @object_id IS NOT NULL 
        BEGIN;
            BEGIN TRANSACTION;
            SET @strSQL = 'TRUNCATE TABLE [' + @strTabla + '];'
            EXECUTE (@strSQL);
            COMMIT TRANSACTION;
        END;
    ELSE
    BEGIN;
        PRINT N'La Tabla: ' + @strTabla + ' No existe';
    END;
END TRY
BEGIN CATCH  
    -- se presento un error en la ejcución y s epresenta
    PRINT N'Se presento el error: ';
    SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage;   
END CATCH;
Yimy
fonte
11
Isso parece muito semelhante ao código em outra resposta. Você é o mesmo usuário que esse?
precisa saber é o seguinte
@ ypercubeᵀᴹ - Ele está expandindo a resposta anterior adicionando código para proteger contra injeção de SQL.
Graeme
-1

Tanto quanto eu entendo Truncar não é algo que você pode reverter. Portanto, a transação de início / transação de confirmação é desnecessária.

Brian Clark
fonte
isso não é verdade e é fácil testar, por favor, exclua \ altere esta resposta
Marcello Miorelli
BEGIN TRANSACTION RADHE SELECT @@TRANCOUNT select * from [dbo].[mytable] truncate table [dbo].[mytable] rollback select * from [dbo].[mytable] /*COMMIT TRAN RADHE*/ SELECT @@TRANCOUNT
Marcello Miorelli 9/04