J'ai un compte SQL avec les autorisations suivantes sur une base de données:
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?
Le meilleur endroit pour rechercher ces informations est dans les livres en ligne. L'article sur 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.
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.
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;
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;
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.