在本课中,您将创建表、触发器和用于处理更新的存储过程。
上下文和注释
若要处理上载,必须确保根据构建上载时的开始进度使用正确的前映像。
使用连接到远程数据库的 Interactive SQL 实例,创建一个表,该表用于维护已更新行的前映像。生成脚本式上载时将使用前映像。
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 ) ); |
接下来,创建一个触发器,此触发器在更新每一行时存储该行的前映像。与插入触发器一样,下载时不触发此触发器。
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; |
每次更新行时,此触发器均存储前映像行(除非两次更新时间太近,致使它们获得相同的时间戳)。乍看起来这种方法浪费了资源。只有在表中没有行的前映像时才存储前映像,在上载前映像后依靠 sp_hook_dbmlsync_upload_end 挂接将其删除,这种方法更具吸引力。
但是,sp_hook_dbmlsync_upload_end 挂接在这种方法中并不可靠。如果在发送上载后确认上载前的这段时间内由于发生硬件或软件故障停止了 dbmlsync,则不会调用此挂接,从而导致不会从前映像表中删除行,即使这些行已成功上载。另外,如果发生通信故障,dbmlsync 也不会从服务器收到上载确认。在这种情况下,传送到挂接的上载状态为 'unknown'。如果发生这种情况,则挂接将无法判断前映像表是应该清除还是应该保留原样。通过存储多个前映像,将始终能够根据构建上载时的开始进度选择正确的前映像。
接下来,创建一个用于处理更新的上载过程。
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; |
此存储过程返回一个所包含列数为其它脚本包含列数两倍的结果集:该结果集包含前映像(上次从 MobiLink 服务器接收或成功上载到 MobiLink 服务器时行中的值)和后映像(要输入到统一数据库中的值)。
前映像是 employee_preimages 中在 start_progress 后记录的最早的一组值。此示例不能正确处理删除后再次插入的现有行。在更完整的解决方案中,这些将作为更新上载。
![]() |
使用DocCommentXchange讨论此页。
|
版权 © 2013, SAP 股份公司或其关联公司. - SAP Sybase SQL Anywhere 16.0 |