Allow non-db_owner INSERT permissions in merge replication with auto identity range mgmt

£可爱£侵袭症+ 提交于 2019-12-02 17:14:50

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!