Quelles autorisations sont nécessaires pour tronquer une table?

14

J'ai un compte SQL avec les autorisations suivantes sur une base de données:

entrez la description de l'image ici

Le db_executorrôle dont vous voyez que ce compte est membre a été créé par ce script:

CREATE ROLE [db_executor] AUTHORIZATION [dbo]
GO

GRANT EXECUTE TO [db_executor] 
GO

Quand je lance un select, update, insertou deletesur la table, il fonctionne très bien. Lorsque j'essaie de truncatela table, il me donne ce message d'erreur:

Impossible de trouver l'objet "TableName" car il n'existe pas ou vous ne disposez pas des autorisations.

Quelle autorisation manque ce compte?

Mansfield
la source
TRUNCATE TABLEest DDL, pas DML.
RBarryYoung du

Réponses:

26

Le meilleur endroit pour rechercher ces informations est dans les livres en ligne. L'article TRUNCATE TABLE ici indique:

L'autorisation minimale requise est ALTER sur nom_table. Les autorisations TRUNCATE TABLE sont attribuées par défaut au propriétaire de la table, aux membres du rôle serveur fixe sysadmin et aux rôles de base de données fixes db_owner et db_ddladmin et ne sont pas transférables. Cependant, vous pouvez incorporer l'instruction TRUNCATE TABLE dans un module, tel qu'une procédure stockée, et accorder les autorisations appropriées au module à l'aide de la clause EXECUTE AS.

ALTER correspond donc aux autorisations minimales requises. Vous pouvez l'obtenir en tant que propriétaire de la base de données, vous pouvez l'obtenir en tant que DB_DDLAdmin. Ou accordez simplement alter.

Si vous pensez à ce que fait tronquer et comment cela fonctionne, cela a du sens, c'est une commande assez "sévère" qui vide la table de données et le fait rapidement.

Mike Walsh
la source
12

Selon cette référence dans BOL :

L'autorisation minimale requise est ALTER sur nom_table . Les autorisations TRUNCATE TABLE sont attribuées par défaut au propriétaire de la table , aux membres du rôle serveur fixe sysadmin et aux rôles de base de données fixes db_owner et db_ddladmin et ne sont pas transférables. Cependant, vous pouvez incorporer l'instruction TRUNCATE TABLE dans un module, tel qu'une procédure stockée, et accorder les autorisations appropriées au module à l'aide de la clause EXECUTE AS.

Thomas Stringer
la source
3

Vous pouvez créer une procédure stockée avec execute en tant que propriétaire sur une seule table ou une procédure stockée sur n'importe quelle table. Dans le code suivant est une procédure stockée pour tronquer n'importe quelle table sans attribuer la permission de db_ownerou autre:

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
la source
c'est une bonne idée, mais elle pourrait être bien améliorée. par exemple, en ajoutant try..catch, une autre chose vérifie les contraintes, en particulier les clés étrangères, ainsi que les champs d'identité, doivent les réensemencer. vous pouvez avoir tout cela dans votre procédure. si vous le faites, partagez le nouveau code. ;)
Marcello Miorelli
1

Vous pouvez créer une procédure stockée avec execute en tant que propriétaire sur une seule table ou une procédure stockée sur n'importe quelle table. Dans le code suivant est une procédure stockée pour tronquer n'importe quelle table sans attribuer l'autorisation de db_owner ou autre. Dans cette version de SP est inclus la gestion des erreurs et la prévention de l'injection 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
la source
1
Cela ressemble beaucoup au code d'une autre réponse. Êtes-vous le même utilisateur que celui-là?
ypercubeᵀᴹ
@ ypercubeᵀᴹ - Il développe la réponse précédente en ajoutant du code pour se protéger contre l'injection SQL.
Graeme
-1

Pour autant que je le comprends, tronquer n'est pas quelque chose que vous pouvez annuler. Ainsi, la transaction Begin Transaction / Commit Transaction n'est pas nécessaire.

Brian Clark
la source
ce n'est pas vrai et il est facile de tester s'il vous plaît supprimer \ changer cette réponse
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