テーブルに対する INSERT 権限を持つユーザーがいます。テーブルのプライマリ範囲がなくなるまで、パブリッシャーにレコードを挿入できます。その後、INSERT を実行しようとするたびに、このエラーが発生し始めます。
[Microsoft][ODBC SQL Server ドライバー]端数切り捨て
[Microsoft][ODBC SQL Server ドライバー][SQL Server]挿入に失敗しました。データベース 'TaxDB'、レプリケートされたテーブル 'dbo.ClientHistory'、列 'ClientHistoryID' の ID 範囲チェック制約と競合しました。ID 列がレプリケーションによって自動的に管理される場合は、範囲を次のように更新します。パブリッシャーの場合、sp_adjustpublisheridentityrange を実行します。サブスクライバーの場合は、ディストリビューション エージェントまたはマージ エージェントを実行します。
[Microsoft][ODBC SQL Server Driver][SQL Server]ステートメントは終了しました。ODBC -- リンク テーブル 'ClientHistory' への挿入に失敗しました。
SQL Server 2008 R2のMS ドキュメントによると:
パブリッシャーが挿入後に ID 範囲を使い果たした場合、挿入が db_owner 固定データベース ロールのメンバーによって実行された場合、新しい範囲を自動的に割り当てることができます。挿入がそのロールに属していないユーザーによって実行された場合、ログ リーダー エージェント、マージ エージェント、または db_owner ロールのメンバーであるユーザーは、sp_adjustpublisheridentityrange (Transact-SQL)を実行する必要があります。
そのため、ドキュメントには、ユーザーは「db_owner」ロールのメンバーである必要があると記載されていますが、その理由は記載されていません。自動生成された MSmerge_ins トリガーの 1 つからの 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 パーミッション (ただし、それ以外の場合はパーミッションが制限されている) を持つユーザーに、プライマリ ID 範囲からセカンダリ ID 範囲に切り替える機能を提供したいと考えています。これらのユーザーを 'db_owner's にすることはオプションではありません。ただし、制限付きの追加のアクセス許可を与えることは確かに可能です。それらの権限がどうなるかわかりません。
SQL Server 2008 マージ レプリケーションでは、自動 ID 範囲管理が既定でオンになっているため、すぐに使用できると誤って想定していました。私は ID 範囲管理なしに戻したほうがよいと考え始めています。本当に、管理者が常に介入しなくても、ユーザーがレコードを挿入できるようにしたいだけです。