Какие разрешения необходимы для усечения таблицы?

14

У меня есть учетная запись SQL со следующими разрешениями для базы данных:

введите описание изображения здесь

db_executorРоль , которую вы видите этот счет , будучи членом был создан этим скриптом:

CREATE ROLE [db_executor] AUTHORIZATION [dbo]
GO

GRANT EXECUTE TO [db_executor] 
GO

Когда я побегать select, update, insertили deleteна столе, она работает отлично. Когда я пытаюсь перейти truncateк таблице, мне выдается следующее сообщение об ошибке:

Не удается найти объект «TableName», так как он не существует или у вас нет разрешений.

Какое разрешение этого аккаунта отсутствует?

Mansfield
источник
TRUNCATE TABLEэто DDL, а не DML.
RBarryYoung,

Ответы:

26

Лучшее место для поиска этой информации - в книгах онлайн. Статья TRUNCATE TABLE здесь указывает:

Требуемое минимальное разрешение - ALTER для table_name. Разрешения TRUNCATE TABLE по умолчанию принадлежат владельцу таблицы, членам предопределенной роли сервера sysadmin и предопределенным ролям базы данных db_owner и db_ddladmin и не подлежат передаче. Однако вы можете включить оператор TRUNCATE TABLE в модуль, такой как хранимая процедура, и предоставить соответствующие разрешения модулю, используя предложение EXECUTE AS.

Таким образом, ALTER - это минимальные необходимые разрешения. Вы можете получить это как Владелец БД, вы можете получить это как DB_DDLAdmin. Или просто дайте изменить.

Если вы думаете о том, что делает усечение и как оно работает, это имеет смысл, это довольно «серьезная» команда, которая очищает таблицу данных и делает это быстро.

Майк Уолш
источник
12

Согласно этой ссылке в BOL :

Требуемое минимальное разрешение - ALTER для table_name . Разрешения TRUNCATE TABLE по умолчанию принадлежат владельцу таблицы , членам предопределенной роли сервера sysadmin и предопределенным ролям базы данных db_owner и db_ddladmin и не могут быть переданы. Однако вы можете включить оператор TRUNCATE TABLE в модуль, такой как хранимая процедура, и предоставить соответствующие разрешения модулю, используя предложение EXECUTE AS.

Томас Стрингер
источник
3

Вы можете создать хранимую процедуру с исполнением от имени владельца только для одной таблицы или хранимой процедуры для любой таблицы. В следующем коде хранится процедура обрезания любой таблицы без предоставления разрешения db_ownerили другого:

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
источник
Это хорошая идея, но она может быть улучшена. например, добавив try..catch, еще одна вещь - проверка ограничений, особенно внешних ключей, а также полей идентификаторов, для их повторного заполнения. Вы можете иметь все это в вашей процедуре. если вы это сделаете, поделитесь новым кодом. ;)
Марчелло Миорелли
1

Вы можете создать хранимую процедуру с исполнением от имени владельца только для одной таблицы или хранимой процедуры для любой таблицы. В следующем коде хранится процедура обрезания любой таблицы без предоставления разрешения db_owner или другим. В эту версию SP включена обработка ошибок и предотвращение 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
источник
1
Это выглядит очень похоже на код в другом ответе. Вы тот же пользователь, что и этот?
ypercubeᵀᴹ
@ ypercubeᵀᴹ - он расширяет предыдущий ответ, добавляя код для защиты от внедрения SQL.
Грэм
-1

Насколько я понимаю, Truncate - это не то, что вы можете откатить. Таким образом, Начать транзакцию / Подтвердить транзакцию не нужно.

Брайан Кларк
источник
это не так, и это легко проверить, пожалуйста, удалите \ измените этот ответ
Марчелло Миорелли
BEGIN TRANSACTION RADHE SELECT @@TRANCOUNT select * from [dbo].[mytable] truncate table [dbo].[mytable] rollback select * from [dbo].[mytable] /*COMMIT TRAN RADHE*/ SELECT @@TRANCOUNT
Марчелло Миорелли