问题
I have users with INSERT permissions on a table. They can insert records on the publisher until the table's primary range runs out. Then they start getting this error every time they try to do an INSERT:
[Microsoft][ODBC SQL Server Driver]Fractional truncation
[Microsoft][ODBC SQL Server Driver][SQL Server]The insert failed. It conflicted with an identity range check constraint in database 'TaxDB', replicated table 'dbo.ClientHistory', column 'ClientHistoryID'. If the identity column is automatically managed by replication, update the range as follows: for the Publisher, execute sp_adjustpublisheridentityrange; for the Subscriber, run the Distribution Agent or the Merge Agent.
[Microsoft][ODBC SQL Server Driver][SQL Server]The statement has been terminated. ODBC--insert on a linked table 'ClientHistory' failed.
According to the MS Documentation for SQL Server 2008 R2:
If the Publisher exhausts its identity range after an insert, it can automatically assign a new range if the insert was performed by a member of the db_owner fixed database role. If the insert was performed by a user not in that role, the Log Reader Agent, Merge Agent, or a user who is a member of the db_owner role must run sp_adjustpublisheridentityrange (Transact-SQL).
So the docs say that the user must be a member of the 'db_owner' role but they do not say why. Here is the applicable section of T-SQL from one of the auto-generated MSmerge_ins triggers:
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
I would like to provide users who have INSERT permissions on the table (but otherwise limited permissions) the ability to switch from the primary to secondary identity range. Making these users 'db_owner's is not an option. However, giving them limited additional permissions is certainly a possibility. I just don't know what those permissions would be.
Since auto identity range mgmt is turned on by default in SQL Server 2008 merge replication I incorrectly assumed it would "just work" out of the box. I'm starting to think I'd be better off going back to NO identity range management. Really I just want my users to be able to insert records without needing an admin to step in all the time.
来源:https://stackoverflow.com/questions/6075074/allow-non-db-owner-insert-permissions-in-merge-replication-with-auto-identity-ra