Разрешить не-db_owner разрешения INSERT при репликации слиянием с автоматическим диапазоном идентификаторов mgmt - PullRequest
0 голосов
/ 20 мая 2011

У меня есть пользователи с разрешениями INSERT для таблицы. Они могут вставлять записи на издателе, пока не исчерпается основной диапазон таблицы. Затем они начинают получать эту ошибку каждый раз, когда пытаются сделать ВСТАВКУ:

[Microsoft] [Драйвер ODBC SQL Server] Дробное усечение
[Microsoft] [Драйвер ODBC SQL Server] [SQL Server] Вставка не удалась. Это противоречило ограничению проверки диапазона идентификаторов в базе данных «TaxDB», реплицированной таблице «dbo.ClientHistory», столбце «ClientHistoryID». Если столбец идентификаторов автоматически управляется репликацией, обновите диапазон следующим образом: для издателя выполните sp_adjustpublisheridentityrange; для подписчика запустите агент распространителя или агент слияния.
[Microsoft] [Драйвер ODBC SQL Server] [SQL Server] Оператор был прерван. ODBC - ошибка вставки в связанную таблицу «ClientHistory».

Согласно документации MS для SQL Server 2008 R2:

Если издатель исчерпывает свой диапазон идентификаторов после вставки, он может автоматически назначить новый диапазон, если вставка была выполнена членом предопределенной роли базы данных db_owner. Если вставка была выполнена пользователем, не входящим в эту роль, агент чтения журнала, агент слияния или пользователь, являющийся членом роли db_owner, должны выполнить sp_adjustpublisheridentityrange (Transact-SQL) .

Таким образом, в документах говорится, что пользователь должен быть членом роли 'db_owner', но они не говорят, почему. Вот соответствующий раздел T-SQL от одного из автоматически сгенерированных триггеров MSmerge_ins:

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's не вариант. Однако предоставление им ограниченных дополнительных разрешений, безусловно, возможно. Я просто не знаю, какими будут эти разрешения.

Поскольку в SQL Server 2008 репликация слиянием по умолчанию включена автоматическая идентификация диапазона mgmt, я ошибочно полагал, что она будет «работать» из коробки. Я начинаю думать, что мне было бы лучше вернуться к НИ ОДНОМУ управлению диапазоном идентичности. На самом деле я просто хочу, чтобы мои пользователи могли вставлять записи, не требуя, чтобы администратор все время входил.

...