我正在更新该表的一些记录,之后我需要将此表设置为只读。
那么如何在SQL Server中使表只读?
我正在更新该表的一些记录,之后我需要将此表设置为只读。
那么如何在SQL Server中使表只读?
一个简单的替代方案,可以阻止特定表格的更新和插入,但仍允许删除:
ALTER TABLE mytable WITH NOCHECK ADD CONSTRAINT chk_read_only CHECK( 1 = 0 )
注意: 这个方法可以避免 INSERT 和 UPDATE,但是会允许 DELETE。
你也可以将表放在自己的数据库中,然后将 LOGIN
的权限设置为只读。
另一个主要选择是将只读表移动或重新创建到单独被标记为 READ_ONLY
的 FILEGROUP
中。请注意,PRIMARY
文件组总是需要读写权限,只有 SECONDARY
文件组可以是只读的。
(此解决方案仅适用于本地 SQL Server 安装;在 Azure SQL 中可以手动创建文件组,但该过程有所不同,本文不讨论此点)。
步骤1:创建新的(次要的)FILEGROUP
,最初将具有读写权限:
USE [master];
ALTER DATABASE MyDatabase ADD FILEGROUP MyReadOnlyFileGroup;
ALTER DATABASE MyDatabase ADD FILE (
NAME = N'mydb_readonly_tables',
FILENAME = N'G:\SQL2005DATA\mydb_readonly_tables.ndf', /* .MDF = Primary, .NDF = Secondary */
SIZE = 3072KB, /* SIZE and FILEGROWTH values shown herre are arbitrary. */
FILEGROWTH = 1024KB
) TO FILEGROUP MyReadOnlyFileGroup;
步骤二:将表移动到文件组或重新创建它们(并将数据复制)到新的辅助FILEGROUP
中:
USE MyDatabase;
-- NOTE: Moving tables between filegroups is non-trivial and too complicated to describe in this answer, but see here for more information: https://www.mssqltips.com/sqlservertip/5832/move-sql-server-tables-to-different-filegroups/
-- It is often much simpler to re-CREATE the table and INSERT INTO to copy data over instead, for example:
CREATE TABLE myschema.myReadOnlyTable (
somedata varchar(8000) NOT NULL,
etc int NOT NULL
) ON MyReadOnlyFileGroup;
GO
SET XACT_ABORT ON;
BEGIN TRANSACTION;
INSERT INTO myschema.myReadOnlyTable ( somedata, etc )
SELECT somedata, etc FROM myschema.myMutableTable;
/* DROP TABLE myschema.myMutableTable; -- Uncomment this if you dare.*/
COMMIT TRANSACTION;
步骤三:在新的FILEGROUP
上设置READ_ONLY
选项:
USE [master];
ALTER DATABASE MyDatabase MODIFY FILEGROUP MyReadOnlyFileGroup READ_ONLY;
如果任何连接尝试在一个READ_ONLY
FILEGROUP
中的表上执行任何DML(UPDATE
/INSERT
/DELETE
/MERGE
)或DDL(CREATE
,ALTER
, DROP
)操作,则会失败并显示错误(通常是Msg 652
或Msg 1924
):
Msg 1924, Level 16, State 2, Line 123
Filegroup '
MyReadOnlyFileGroup
' is read-only.
Msg 652, Level 16, State 1, Line 123
The index "PK_Index" for table "
myschema.myReadOnlyTable
" (RowsetId123
) resides on a read-only filegroup ("MyReadOnlyFileGroup
"), which cannot be modified.
因此,为了对表的设计或其中包含的数据进行任何更改,您需要首先重新使用ALTER DATABASE
来删除READ_ONLY
选项(但不必将数据复制回PRIMARY
文件组)。
资源:
ALTER DATABASE [csvtosp] MODIFY FILEGROUP [READONLYTABLES] READONLY
。 - BaodadREADONLYTABLES
不是只读的。第三点可能是最佳实践。例如,如果您的连接是db_owner,则可以禁用触发器或将表移动到不同的文件组。