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

SQL Anywhere 12.0.1 (Deutsch) » MobiLink - Clientadministration » SQL Anywhere-Clients für MobiLink » Skriptgesteuerter Upload » Praktische Einführung: Verwenden des skriptgesteuerten Uploads

 

Lektion 4: Umgang mit Aktualisierungen

In dieser Lektion wird davon ausgegangen, dass Sie bereits alle vorherigen Lektionen abgeschlossen haben. Siehe Lektion 1: Erstellen der konsolidierten Datenbank.

Bei Aktualisierungen müssen Sie zunächst sicherstellen, dass während des Uploads das korrekte Pre-Image basierend auf dem Start-Verarbeitungsfortschritt verwendet wird.

 Umgang mit Aktualisierungen
  1. Wählen Sie die mit der entfernten Datenbank verbundene Instanz von Interactive SQL und erstellen Sie eine Tabelle, in der die Pre-Images der aktualisierten Zeilen verwaltet werden. Die Pre-Images werden für das Generieren der skriptgesteuerten Uploads benötigt.

    CREATE TABLE employee_preimages (
       id           unsigned integer NOT NULL,
       name         varchar( 256),
       salary       numeric( 9, 2 ),
       img_time     timestamp default CURRENT TIMESTAMP,
       primary key( id, img_time )
    );
  2. Erstellen Sie dann einen Trigger, um ein Pre-Image für jede Zeile zu speichern, wenn sie aktualisiert wird. Wie bereits der Insert-Trigger wird dieser Trigger beim Download nicht ausgeführt.

    CREATE TRIGGER emp_upd AFTER UPDATE OF name,salary ON employee
       REFERENCING OLD AS oldrow
       FOR EACH ROW
    BEGIN
       INSERT INTO employee_preimages ON EXISTING SKIP VALUES(
          oldrow.id, oldrow.name, oldrow.salary, CURRENT TIMESTAMP );
    END;

    Beachten Sie, dass dieser Trigger ein Pre-Image der Zeile speichert, sobald die Zeile aktualisiert wird (Ausnahme: Zwei Aktualisierungen liegen so nah beieinander, dass sie denselben Zeitstempel erhalten). Auf den ersten Blick erscheint dies überflüssig. Man könnte versucht sein, ein Pre-Image nur dann zu speichern, wenn dieses für die entsprechende Zeile in der Tabelle nicht existiert, und dann mithilfe des Hooks sp_hook_dbmlsync_upload_end die Pre-Images zu löschen, sobald sie heraufgeladen wurden.

    Der Hook sp_hook_dbmlsync_upload_end ist hierfür jedoch nicht zuverlässig genug. Der Hook wird beispielsweise nicht aufgerufen, wenn dbmlsync aufgrund eines Hard- oder Softwarefehlers gestoppt wird, nachdem der Upload gesendet, aber noch nicht bestätigt wurde. Dies führt dazu, dass Zeilen nicht aus Pre-Image-Tabellen gelöscht werden, obwohl sie erfolgreich heraufgeladen wurden. Auch ein Verbindungsfehler kann dazu führen, dass dbmlsync keine Bestätigung für einen Upload vom Server erhält. In diesem Fall wird dem Hook der Upload-Status 'unknown' übergeben. Dann kann der Hook nicht erkennen, ob die Pre-Image-Tabelle bereinigt werden muss oder unverändert bleiben soll. Beim Speichern mehrerer Pre-Images kann das korrekte Pre-Image basierend auf dem Start-Verarbeitungsfortschritt beim Upload ausgewählt werden.

  3. Erstellen Sie als Nächstes eine Upload-Prozedur für das Bearbeiten von Aktualisierungen.



    CREATE PROCEDURE employee_update()
    RESULT(
           preimage_id  unsigned integer,
           preimage_name varchar( 256),
           preimage_salary numeric( 9,2 ),
           postimage_id  unsigned integer,
           postimage_name varchar( 256),
           postimage_salary numeric( 9,2 )
          )
    BEGIN
        DECLARE start_time timestamp;
    
        SELECT value
        INTO start_time
        FROM #hook_dict
        WHERE name = 'start progress as timestamp';
    
        // Upload as an update all rows that have been updated since 
        // start_time that were not newly inserted or deleted.
        SELECT ep.id, ep.name, ep.salary, e.id, e.name, e.salary
        FROM employee e JOIN employee_preimages ep 
            ON ( e.id = ep.id )
        // Do not select rows inserted since the start time. These should be
        // uploaded as inserts.
        WHERE insert_time <= start_time 
          // Do not upload deleted rows.
          AND NOT EXISTS( SELECT id FROM employee_delete ed  WHERE ed.id = e.id )
          // Select the earliest pre-image after the start time.
          AND ep.img_time = ( SELECT MIN( img_time )
                FROM employee_preimages
                WHERE id = ep.id
                AND img_time > start_time );
    END;

    Diese gespeicherte Prozedur gibt eine Ergebnismenge mit doppelt so vielen Spalten zurück wie andere Skripten: Sie enthält das Pre-Image (die Werte in der Zeile zu dem Zeitpunkt, als sie das letzte Mal vom MobiLink-Server empfangen oder erfolgreich heraufgeladen wurden) und das Post-Image (die Werte, die in die konsolidierte Datenbank eingegeben werden sollen).

    Das Pre-Image ist die erste Wertemenge in employee_preimages, die nach start_progress aufgezeichnet wurde. Beachten Sie, dass in diesem Beispiel bestehende Zeilen, die gelöscht und erneut eingefügt werden, nicht korrekt verarbeitet werden. In einer komplexeren Lösung würden diese als Aktualisierung heraufgeladen werden.

  4. Fahren Sie fort mit Lektion 5: Umgang mit Löschungen.