0

別のデータベースに (マージ レプリケーションを使用して) レプリケートされ、ストアド プロシージャである 1 つのカスタム リゾルバーを持つデータベースにポストする C# アプリケーションがあります。

これは SQL Server 2000 では正常に機能していましたが、SQL Server 2005 でテストすると、カスタム リゾルバーは空の varchar 列を null に変更しようとします (この特定の列は null を許可しないので失敗します)。

これらの varchar フィールドは、両方のデータベースで現在空であり、変更されておらず、ストアド プロシージャがそれらを変更していないため、競合を引き起こすものではないことに注意してください (別の money 列の値を設定しようとしているだけです)。 .

誰かがこの問題に遭遇したことがありますか、または空の文字列をそのまま残すストアドプロシージャの例がありますか?

実際のストアド プロシージャはかなり単純で、競合が発生した場合に顧客の残高を再計算します。

ALTER procedure [dbo].[ReCalculateCustomerBalance]
    @tableowner sysname,
    @tablename sysname,
    @rowguid varchar(36),
    @subscriber sysname,
    @subscriber_db sysname,
    @log_conflict INT OUTPUT,
    @conflict_message nvarchar(512) OUTPUT
AS
    set nocount on
DECLARE
    @CustomerID  bigint,
    @SysBalance money,
    @CurBalance money,
    @SQL_TEXT nvarchar(2000)

    Select @CustomerID = customer.id from customer where rowguid=  @rowguid

    Select @SysBalance = Sum(SystemTotal), @CurBalance = Sum(CurrencyTotal)  From CustomerTransaction Where CustomerTransaction.CustomerID = @CustomerID

    Update Customer Set SystemBalance = IsNull(@SysBalance, 0), CurrencyBalance = IsNull(@CurBalance, 0) Where id = @CustomerID

    Select * From Customer Where rowguid= @rowguid

    Select @log_conflict =0
    Select @conflict_message ='successful'
    Return(0)
4

1 に答える 1

0

ここにはいくつかのオプションがあります。それぞれが、私の調査によると、SQL Server の問題であると思われることからのちょっとした回避策です。

1- このステートメントを変更Select * From Customer Where rowguid= @rowguidします: 各列を明示的に言及し、問題のあるフィールドに「isNull」を使用します

2- 表の列を変更して、「」のデフォルトの制約を追加します。これにより、「null」を挿入しようとすると、空の文字列に置き換えられます

3-「null」を含まないように、挿入前にデータを変更する「before insert」トリガーを追加します

PS: レプリケーション システムに「必須」とマークされた列があることを確信していますか? 必要がなければ、データが存在しない場合は「null」を挿入すると思います。

于 2009-10-05T17:27:14.013 に答える