Lesson 5: Handling deletes

This lesson assumes you have completed all preceding lessons. See Lesson 1: Creating the consolidated database.

 Handle deletes
  1. Using the instance of Interactive SQL connected to the remote database, create a table to maintain a list of deleted rows:

    CREATE TABLE employee_delete (
        id           unsigned integer  primary key NOT NULL,
        name         varchar( 256 ),
        salary       numeric( 9, 2 ),
        delete_time  timestamp
    );
  2. Next, create a trigger to populate the employee_delete table as rows are deleted from the employee table.

    CREATE TRIGGER emp_del AFTER DELETE ON employee
    REFERENCING OLD AS delrow
    FOR EACH ROW
    BEGIN
         INSERT INTO employee_delete 
    VALUES( delrow.id, delrow.name, delrow.salary, CURRENT TIMESTAMP );
    END;

    This trigger is not called during download because later you set the dbmlsync extended option FireTriggers to false. Note that this trigger assumes that a deleted row is never reinserted; therefore it does not deal with the same row being deleted more than once.

  3. The next SQL statement creates an upload procedure to handle deletes.



    CREATE PROCEDURE employee_delete()
    RESULT( id  unsigned integer,
              name varchar( 256),
              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 a delete all rows that were deleted after the 
       // start_time that were not inserted after the start_time.
       // If a row was updated before it was deleted, then the row
       // to be deleted is the pre-image of the update.
        SELECT IF ep.id IS NULL THEN ed.id ELSE ep.id ENDIF,
               IF ep.id IS NULL THEN ed.name ELSE ep.name ENDIF,
               IF ep.id IS NULL THEN ed.salary ELSE ep.salary ENDIF
        FROM employee_delete ed LEFT OUTER JOIN employee_preimages ep
              ON( ed.id = ep.id AND ep.img_time > start_time )
        WHERE
          // Only upload deletes that occurred since the last sync.
          ed.delete_time > start_time
          // Don't upload a delete for rows that were inserted since 
          // the last upload and then deleted.
        AND NOT EXISTS ( 
          SELECT id
             FROM employee e
             WHERE e.id = ep.id AND e.insert_time > start_time )
        // Select the earliest preimage after the start time.
        AND ( ep.id IS NULL OR ep.img_time = (SELECT MIN( img_time )
                                              FROM employee_preimages
                                              WHERE id = ep.id
                                               AND img_time > start_time ) );
    END;

    This stored procedure returns a result set that contains the rows to delete on the consolidated database. The stored procedure uses the employee_preimages table so that if a row is updated and then deleted, the image uploaded for the delete is the last one that was successfully downloaded or uploaded.

  4. Proceed to Lesson 6: Clearing out the pre-image table.