Izin apa yang diperlukan untuk memotong tabel?

14

Saya memiliki akun SQL dengan izin berikut pada database:

masukkan deskripsi gambar di sini

The db_executorPeran Anda melihat akun ini menjadi anggota diciptakan oleh script ini:

CREATE ROLE [db_executor] AUTHORIZATION [dbo]
GO

GRANT EXECUTE TO [db_executor] 
GO

Ketika saya menjalankan select, update, insertatau deletedi atas meja, itu bekerja dengan baik. Ketika saya mencoba ke truncatetabel, itu memberi saya pesan kesalahan ini:

Tidak dapat menemukan objek "TableName" karena tidak ada atau Anda tidak memiliki izin.

Izin apa yang hilang dari akun ini?

Mansfield
sumber
TRUNCATE TABLEadalah DDL, bukan DML.
RBarryYoung

Jawaban:

26

Tempat terbaik untuk mencari informasi ini ada di buku online. Artikel di TRUNCATE TABLE sini menunjukkan:

Izin minimum yang diperlukan adalah ALTER di table_name. TRUNCATE TABLE izin default untuk pemilik tabel, anggota peran server tetap sysadmin, dan peran basis data tetap db_owner dan db_ddladmin, dan tidak dapat ditransfer. Namun, Anda dapat memasukkan pernyataan TRUNCATE TABLE dalam modul, seperti prosedur tersimpan, dan memberikan izin yang sesuai untuk modul menggunakan klausa EXECUTE AS.

Jadi ALTER adalah izin minimum yang diperlukan. Anda bisa mendapatkannya sebagai Pemilik DB, Anda bisa mendapatkannya sebagai DB_DDLAdmin. Atau berikan saja alter.

Jika Anda berpikir tentang apa yang dipotong dan bagaimana cara kerjanya, ini masuk akal, itu adalah perintah yang cukup "parah" dan mengosongkan tabel data dan melakukannya dengan cepat.

Mike Walsh
sumber
12

Sesuai referensi ini di BOL :

Izin minimum yang diperlukan adalah ALTER di table_name . TRUNCATE TABLE izin default untuk pemilik tabel , anggota peran server tetap sysadmin , dan peran basis data tetap db_owner dan db_ddladmin , dan tidak dapat ditransfer. Namun, Anda dapat memasukkan pernyataan TRUNCATE TABLE dalam modul, seperti prosedur tersimpan, dan memberikan izin yang sesuai untuk modul menggunakan klausa EXECUTE AS.

Thomas Stringer
sumber
3

Anda bisa membuat prosedur tersimpan dengan menjalankan sebagai pemilik hanya satu tabel atau prosedur tersimpan ke tabel apa pun. Dalam kode selanjutnya disimpan prosedur untuk memotong tabel apa pun tanpa izin db_owneratau dari yang lain:

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
sumber
ini adalah ide yang bagus, tetapi bisa ditingkatkan dengan baik. misalnya, menambahkan try..catch, hal lain adalah memeriksa kendala, khususnya kunci asing, juga bidang identitas, perlu di-reseed. Anda dapat memiliki semua itu dalam prosedur Anda. jika Anda melakukannya, bagikan kode baru. ;)
Marcello Miorelli
1

Anda bisa membuat prosedur tersimpan dengan menjalankan sebagai pemilik hanya satu tabel atau prosedur tersimpan ke tabel apa pun. Dalam kode selanjutnya disimpan prosedur untuk memotong tabel apa pun tanpa izin db_owner atau lainnya. Dalam versi SP ini termasuk penanganan kesalahan dan pencegahan 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;
Yimy
sumber
1
Ini terlihat sangat mirip dengan kode di jawaban lain. Apakah Anda pengguna yang sama dengan yang itu?
ypercubeᵀᴹ
@ ypercubeᵀᴹ - Dia memperluas jawaban sebelumnya dengan menambahkan kode untuk melindungi terhadap injeksi SQL.
Graeme
-1

Sejauh yang saya mengerti, Truncate bukanlah sesuatu yang dapat Anda kembalikan. Jadi Transaksi Begin / Transit Komit tidak perlu.

Brian Clark
sumber
ini tidak benar dan mudah untuk diuji tolong hapus \ ubah jawaban ini
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