0

Microsoft SQL Server データベースには通知システムがあります。NotifyOnPropertyChangedTrigger という SQL トリガーによってファイルが作成されます。当社のクライアント ソフトウェアは、.NET FileSystemWatcher クラスを使用して新しいファイルが表示されるのを待機し、ファイルを読み取って新しいプロパティ設定を取得します。SQL レプリケーションが関係しない限り、これはうまく機能します。

問題は次のようになります。

そこで、メイン データベースに変更を挿入します (これは、他の 3 つの SQL Server DB にレプリケートされます)。変更は SQL トリガーによって検出され、ファイルはハード ディスク上に正しく作成されます。DB レプリケーションは、他の 3 つの DQL DB を正しく更新して、最新の変更を反映します。ただし、トリガーはたまにしか機能しないため、他の 3 台のハード ディスクのそれぞれにファイルが常に作成されるとは限りません。(どのようにすべきか。合計 4 つのファイル: マスター DB で作成された 1 つ、レプリケーション DB で作成された 3 つ)

マージ レプリケーションを使用しています。

なぜこれが起こるのでしょうか?

前もって感謝します。

トリガーは次のとおりです。

ALTER TRIGGER [dbo].[NotifyOnPropertyChangeTrigger] 
   ON [dbo].[PropertyValues] 
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
    SET NOCOUNT ON

    DECLARE @propertyValueID int

    DECLARE PropertyValueCursor CURSOR FOR
    SELECT DISTINCT [PropertyValueID]
    FROM (SELECT [PropertyValueID] FROM inserted
          UNION ALL
          SELECT [PropertyValueID] FROM deleted) AS Combined

    OPEN PropertyValueCursor
    FETCH NEXT FROM PropertyValueCursor INTO @propertyValueID

    WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE @propertyID int
        DECLARE @profileID int
        DECLARE @contractName nvarchar(255)

        IF ((SELECT COUNT(*) FROM inserted WHERE [PropertyValueID] = @propertyValueID) > 0)
        BEGIN
            SELECT @propertyID = [PropertyID], @profileID = [ProfileID], @contractName = [ContractName]
            FROM inserted
        END
        ELSE
        BEGIN
            SELECT @propertyID = [PropertyID], @profileID = [ProfileID], @contractName = [ContractName]
            FROM deleted
        END

        DECLARE @propertyName nvarchar(255)
        DECLARE @needToSendNotification bit
        SELECT @propertyName = [PropertyName], @needToSendNotification = [NotifyOnUpdate]
        FROM [Properties]
        WHERE [PropertyID] = @propertyID

        IF (@needToSendNotification = 1)
        BEGIN
            DECLARE @profileName nvarchar(50)
            SELECT @profileName = [ProfileName]
            FROM [Profiles]
            WHERE [ProfileID] = @profileID

            DECLARE @fileName nvarchar(600) -- Must be at least 50 + 1 + 255 + 1 + 255 + 19 + 4
            SET @fileName =   dbo.CleanStringForFileName(@profileName)
                            + '-'
                            + dbo.CleanStringForFileName(@contractName)
                            + '-'
                            + dbo.CleanStringForFileName(@propertyName)
                            + '-'
                            + dbo.GetUTCDateTimeStampWithSeparator('-')
                            + '.txt'

            DECLARE @commandString nvarchar(650) -- Must be at least 5 + 10 + 27 + 585
            SET @commandString = 'echo ' + CAST(@propertyValueID AS nvarchar(10)) + ' >> C:\ClientNotifications\' + @fileName

            EXEC master.dbo.xp_cmdshell @commandString, NO_OUTPUT
        END

        FETCH NEXT FROM PropertyValueCursor INTO @propertyValueID
    END

    CLOSE PropertyValueCursor
    DEALLOCATE PropertyValueCursor
END
4

0 に答える 0