web-dev-qa-db-fra.com

Quelles autorisations sont nécessaires pour tronquer une table?

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

enter image description here

Le db_executor le rô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

Lorsque je lance un select, update, insert ou delete sur la table, cela fonctionne très bien. Lorsque j'essaie de truncate la table, cela 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?

14
Mansfield

Le meilleur endroit pour rechercher ces informations est dans les livres en ligne. L'article sur TRUNCATE TABLEici 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.

26
Mike Walsh

Selon cette référence dans BOL :

L'autorisation minimale requise est ALTER sur nom_table. Les autorisations TRUNCATE TABLE sont par défaut le propriétaire de la table, les membres du rôle serveur fixe sysadmin et le db_owner et db_ddladmin fixe les rôles de base de données 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.

12
Thomas Stringer

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:

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;
3
user3854427

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;
0
Yimy

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.

0
Brian Clark