Những quyền nào là cần thiết để cắt bớt một bảng?


14

Tôi có một tài khoản SQL với các quyền sau trên cơ sở dữ liệu:

nhập mô tả hình ảnh ở đây

Các db_executorvai trò mà bạn nhìn thấy tài khoản này là một thành viên của được tạo ra bởi kịch bản này:

CREATE ROLE [db_executor] AUTHORIZATION [dbo]
GO

GRANT EXECUTE TO [db_executor] 
GO

Khi tôi chạy một select, update, inserthoặc deletetrên bàn, nó hoạt động tốt. Khi tôi cố gắng vào truncatebảng, nó sẽ cho tôi thông báo lỗi này:

Không thể tìm thấy đối tượng "TableName" vì nó không tồn tại hoặc bạn không có quyền.

Tài khoản này bị thiếu gì?


TRUNCATE TABLElà DDL, không phải DML.
RBarryYoung

Câu trả lời:


26

Nơi tốt nhất để tìm kiếm thông tin này là trong sách trực tuyến. Bài viết trên TRUNCATE TABLE đây chỉ ra:

Quyền tối thiểu được yêu cầu là ALTER trên tên_bảng. Quyền TRUNCATE TABLE mặc định cho chủ sở hữu bảng, các thành viên của vai trò máy chủ cố định sysadmin và vai trò cơ sở dữ liệu cố định db_owner và db_ddladmin và không thể chuyển nhượng được. Tuy nhiên, bạn có thể kết hợp câu lệnh TRUNCATE TABLE trong một mô-đun, chẳng hạn như thủ tục được lưu trữ và cấp quyền thích hợp cho mô-đun bằng mệnh đề EXECUTE AS.

Vì vậy, ALTER là quyền tối thiểu cần thiết. Bạn có thể lấy đó làm Chủ sở hữu DB, bạn có thể lấy đó là DB_DDLAdmin. Hoặc chỉ cấp thay đổi.

Nếu bạn nghĩ về những gì cắt ngắn làm và cách thức hoạt động, điều này có ý nghĩa, đó là một lệnh khá "nghiêm trọng" và làm trống bảng dữ liệu và thực hiện nhanh chóng.


12

Theo tài liệu tham khảo này trong BOL :

Quyền tối thiểu được yêu cầu là ALTER trên tên_bảng . Quyền TRUNCATE TABLE mặc định cho chủ sở hữu bảng , các thành viên của vai trò máy chủ cố định sysadmin và vai trò cơ sở dữ liệu cố định db_ownerdb_ddladmin và không thể chuyển nhượng được. Tuy nhiên, bạn có thể kết hợp câu lệnh TRUNCATE TABLE trong một mô-đun, chẳng hạn như thủ tục được lưu trữ và cấp quyền thích hợp cho mô-đun bằng mệnh đề EXECUTE AS.


3

Bạn có thể tạo một thủ tục được lưu trữ với thực thi là chủ sở hữu chỉ một bảng hoặc một thủ tục được lưu trữ cho bất kỳ bảng nào. Trong mã tiếp theo được lưu trữ thủ tục để cắt bất kỳ bảng nào mà không cần xin phép db_ownerhoặc khác:

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;

Đây là một ý tưởng tốt, nhưng nó có thể được cải thiện tốt. chẳng hạn, thêm try..catch, một điều nữa là kiểm tra các ràng buộc, các khóa ngoại đặc biệt, cũng như các trường định danh, cần phải định lại chúng. bạn có thể có tất cả những gì trong thủ tục của bạn. nếu bạn làm điều đó, chia sẻ mã mới. ;)
Marcello Miorelli

0

Bạn có thể tạo một thủ tục được lưu trữ với thực thi là chủ sở hữu chỉ một bảng hoặc một thủ tục được lưu trữ cho bất kỳ bảng nào. Trong mã tiếp theo được lưu trữ thủ tục để cắt bất kỳ bảng nào mà không cần sự cho phép của db_owner hoặc khác. Trong phiên bản SP này được bao gồm xử lý lỗi và ngăn ngừa SQL Injection

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;

1
Điều này trông rất giống với mã trong một câu trả lời khác. Bạn có phải là người dùng giống như vậy không?
ypercubeᵀᴹ

-1

Theo như tôi hiểu thì Truncate không phải là thứ bạn có thể quay trở lại. Vì vậy, Giao dịch Bắt đầu / Giao dịch Cam kết là không cần thiết.


Điều này không đúng và rất dễ kiểm tra, vui lòng xóa \ thay đổi câu trả lời này
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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.