0

テーブルに対する 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 範囲管理なしに戻したほうがよいと考え始めています。本当に、管理者が常に介入しなくても、ユーザーがレコードを挿入できるようにしたいだけです。

4

0 に答える 0