Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (Deutsch) » SQL Remote » SQL Remote-Replikationsplanung » SQL Remote-Replikation planen und einrichten » Überlappungspartitionen verwenden

 

Referenzielle Integrität bewahren, wenn Zeilen Subskribenten neu zugewiesen werden

Um eine Geschäftsbeziehung zwischen einem Kunden und einem Handelsvertreter zu beenden, wird eine Zeile in der Policy-Tabelle gelöscht. In diesem Beispiel wird die Änderung an der Policy-Tabelle korrekt an den alten Handelsvertreter repliziert. Es wurden allerdings keine Änderungen in der Customers-Tabelle durchgeführt, und daher werden auch keine Änderungen in der Customers-Tabelle an den alten Handelsvertreter repliziert.

Ohne Trigger kann das zu inkorrekten Daten in der Customers-Tabelle eines Subskribenten führen. Die gleiche Art von Problem taucht auf, wenn eine neue Zeile der Policy-Tabelle hinzugefügt wird.

Mit Triggern das Problem lösen

Die Lösung liegt darin, BEFORE-Trigger zu schreiben, die ausgelöst werden, wenn Änderungen an der Policy-Tabelle durchgeführt werden. Diese speziellen Trigger führen keine Änderungen an Datenbanktabellen durch, setzen aber einen Eintrag in das Transaktionslog, das SQL Remote verwendet, um Daten in Subskribenten-Datenbanken aufrechtzuerhalten.

Ein BEFORE INSERT-Trigger

Beispiel: Die folgenden Anweisungen erstellen einen BEFORE INSERT-Trigger, der Einfügungen in der Policy-Tabelle protokolliert und sicherstellt, dass die entfernten Datenbanken die korrekten Daten enthalten.

CREATE TRIGGER InsPolicy
BEFORE INSERT ON Policy
REFERENCING NEW AS NewRow
FOR EACH ROW
BEGIN
   UPDATE Customers
   PUBLICATION SalesRepData
   SUBSCRIBE BY (
      SELECT rep_key
      FROM Policy
      WHERE cust_key = NewRow.cust_key
      UNION ALL
      SELECT NewRow.rep_key
   )
   WHERE cust_key = NewRow.cust_key;
END;
Ein BEFORE DELETE-Trigger

Die folgenden Anweisungen erstellen einen BEFORE DELETE-Trigger, der Löschungen in der Policy-Tabelle protokolliert:

CREATE TRIGGER DelPolicy
BEFORE DELETE ON Policy
REFERENCING OLD AS OldRow
FOR EACH ROW
BEGIN
   UPDATE Customers
   PUBLICATION SalesRepData
   SUBSCRIBE BY (
      SELECT rep_key
      FROM Policy
      WHERE cust_key = OldRow.cust_key
      AND Policy_key <> OldRow.Policy_key
   )
   WHERE cust_key = OldRow.cust_key;
END;

Die SUBSCRIBE BY-Klausel der UPDATE PUBLICATION-Anweisung enthält eine Unterabfrage, und diese Unterabfrage kann mehrwertig sein.

Mehrwertige Unterabfragen

Die Unterabfrage in der SUBSCRIBE-Klausel von UPDATE PUBLICATION ist ein UNION-Ausdruck und kann mehrwertig sein:

...
SELECT rep_key
FROM Policy
WHERE cust_key = NewRow.cust_key
UNION ALL
SELECT NewRow.rep_key
...
  • Der erste Teil von UNION ist die Menge von vorhandenen Handelsvertretern, die den Kunden betreuen. Er wird der "Policy"-Tabelle entnommen.

    Die Ergebnismenge der Subskriptionsabfrage muss aus all den Handelsvertretern bestehen, die die Zeile empfangen, und nicht nur aus den neuen Handelsvertretern.

  • Der zweite Teil des UNION-Ausdrucks ist der der INSERT-Anweisung entnommene rep_key-Wert für den neuen Handelsvertreter, der den Kunden betreut.

Die Unterabfrage im BEFORE DELETE-Trigger ist mehrwertig:

...
SELECT rep_key
FROM Policy
WHERE cust_key = OldRow.cust_key
AND rep_key <> OldRow.rep_key
...
  • Die Unterabfrage nimmt rep_key-Werte aus der Policy-Tabelle. Die Werte enthalten die Primärschlüssel-Werte von allen Handelsvertretern, die den Kunden betreuen, der übertragen wird (WHERE cust_key = OldRow.cust_key), mit Ausnahme dessen, der gelöscht wird (AND rep_key <> OldRow.rep_key).

    Die Ergebnismenge der Subskriptionsabfrage muss aus all jenen Werten bestehen, die Handelsvertretern entsprechen, welche die Zeile erhalten, nachdem die Löschung erfolgte.

Hinweise
  • Daten in der Customers-Tabelle werden nicht einem bestimmten Subskribenten zugeordnet (zum Beispiel durch einen Primärschlüssel-Wert) und werden von mehr als einem Subskribenten gemeinsam genutzt. Dadurch wird es möglich, Daten an mehr als einem entfernten Standort zwischen den einzelnen Replikatnachrichten zu aktualisieren, was zu Replikationskonflikten führen kann. Sie können dieses Problem entweder durch Berechtigungen lösen (indem Sie z.B. nur bestimmten Benutzern das Aktualisieren der Customers-Tabelle erlauben) oder indem Sie der Datenbank RESOLVE UPDATE-Trigger hinzufügen, die diese Konflikte programmiertechnisch lösen.

  • Aktualisierungen in der Policy-Tabelle wurden hier nicht beschrieben. Sie sollten entweder vermieden werden oder Sie müssen einen BEFORE UPDATE-Trigger erstellen, der die Funktionen der BEFORE INSERT- und BEFORE DELETE-Trigger kombiniert, wie im Beispiel gezeigt.