У меня есть пользователи с разрешениями 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, я ошибочно полагал, что она будет «работать» из коробки. Я начинаю думать, что мне было бы лучше вернуться к НИ ОДНОМУ управлению диапазоном идентичности. На самом деле я просто хочу, чтобы мои пользователи могли вставлять записи, не требуя, чтобы администратор все время входил.