我的用户拥有对表的INSERT权限。他们可以在发布者上插入记录,直到表的主要范围用完为止。然后他们每次尝试执行INSERT时都会收到此错误:
[Microsoft] [ODBC SQL Server驱动程序]分数截断
[Microsoft] [ODBC SQL Server驱动程序] [SQL Server]插入失败。它与数据库'TaxDB'中的标识范围检查约束,复制表'dbo.ClientHistory',列'ClientHistoryID'冲突。如果通过复制自动管理标识列,请按如下所示更新范围:对于Publisher,执行sp_adjustpublisheridentityrange;对于订阅服务器,运行分发代理程序或合并代理程序 [Microsoft] [ODBC SQL Server驱动程序] [SQL Server]该语句已终止。 ODBC - 在链接表'ClientHistory'上插入失败。
根据SQL Server 2008 R2的MS Documentation:
如果发布者在插入后耗尽其标识范围,则如果插入是由db_owner固定数据库角色的成员执行的,则它可以自动分配新范围。如果插入是由不在该角色的用户执行的,则日志读取器代理,合并代理或作为db_owner角色成员的用户必须运行sp_adjustpublisheridentityrange (Transact-SQL)。
因此,文档说用户必须是'db_owner'角色的成员,但他们没有说明原因。以下是来自其中一个自动生成的MSmerge_ins触发器的T-SQL的适用部分:
if is_member('db_owner') = 1
begin
-- select the range values from the MSmerge_identity_range table
-- this can be hardcoded if performance is a problem
declare @range_begin numeric(38,0)
declare @range_end numeric(38,0)
declare @next_range_begin numeric(38,0)
declare @next_range_end numeric(38,0)
select @range_begin = range_begin,
@range_end = range_end,
@next_range_begin = next_range_begin,
@next_range_end = next_range_end
from dbo.MSmerge_identity_range where artid='A2D114CE-8436-48BF-9235-E47A059ACB13' and subid='2689FFDE-991E-4122-BFC2-C9739CC55917' and is_pub_range=0
if @range_begin is not null and @range_end is not NULL and @next_range_begin is not null and @next_range_end is not NULL
begin
if IDENT_CURRENT('[dbo].[ClientHistory]') = @range_end
begin
DBCC CHECKIDENT ('[dbo].[ClientHistory]', RESEED, @next_range_begin) with no_infomsgs
end
else if IDENT_CURRENT('[dbo].[ClientHistory]') >= @next_range_end
begin
exec sys.sp_MSrefresh_publisher_idrange '[dbo].[ClientHistory]', '2689FFDE-991E-4122-BFC2-C9739CC55917', 'A2D114CE-8436-48BF-9235-E47A059ACB13', 2, 1
if @@error<>0 or @retcode<>0
goto FAILURE
end
end
end
我想提供对表具有INSERT权限的用户(但权限有限)能够从主要身份范围切换到次要身份范围。使这些用户的db_owner不是一个选项。但是,给他们有限的额外权限肯定是可能的。我只是不知道那些权限是什么。
由于默认情况下在SQL Server 2008合并复制中打开了自动标识范围mgmt,因此我错误地认为它将“正常工作”开箱即用。我开始认为回到无身份范围管理会更好。真的,我只是希望我的用户能够插入记录而无需管理员随时进入。