DEFINE VARIABLE i AS INTEGER NO-UNDO.
/* An outer loop for batch updates to Customer records */ FOR EACH Customer WHERE CustNum < 2: /* Customer buffer scoped to FOR EACH. Will be available to inner CATCH. */ ASSIGN Customer.Name = Customer.Name + "_changed". /* Update Order records for current Customer. */ DO i = 1 TO 5 ON ERROR UNDO, LEAVE: IF i = 1 then FIND FIRST Order OF Customer. ELSE FIND NEXT Order OF Customer. /* Order record scoped to the DO block, which is the associated block. */ ASSIGN Order.PromiseDate = TODAY. /* Nonsense code raises unique index error. DO block undone. Control passes to CATCH */ ASSIGN Customer.CustNum = 2. CATCH eSysError AS Progress.Lang.SysError: /* MESSAGE statement executes to display available Customer data. Unavailable Order data raises two errors. Errors thrown to FOR EACH block. FOR EACH block undoes iteration and attempts NEXT iteration. Since there is not another iteration, FOR EACH completes. */ MESSAGE Customer.Name SKIP Order.OrderNum Order.PromiseDate VIEW-AS ALERT-BOX BUTTONS OK. END CATCH. END. /* DO */ END. /* FOR EACH */ FIND Customer WHERE Customer.CustNum = 1. /* Demonstrates change made in FOR EACH block is also undone. */ MESSAGE Customer.Name VIEW-AS ALERT-BOX BUTTONS OK. |
/* Defines an undoable variable because the NO-UNDO option is not specified. */
DEFINE VARIABLE TargetCustNum AS INTEGER. /* The last valid value before the beginning of the DO block */ ASSIGN TargetCustNum = 1. /* Outer DO */ DO ON ERROR UNDO, LEAVE: /* Customer buffer is scoped outside of the associated block */ FIND Customer WHERE CustNum = TargetCustNum. DISPLAY Customer.Name WITH SIDE-LABELS. /* Inner DO and also the associated block*/ DO ON ERROR UNDO, LEAVE: /* This value will be undone on ERROR! */ ASSIGN TargetCustNum = 15. /* Find a Customer */ FIND Customer WHERE Customer.CustNum = TargetCustNum. /* Change the database! A transaction is now active. */ ASSIGN Customer.Name = Customer.NAME + " And Much More". /* Confirm change to persistent field. */ MESSAGE "Name changed to: " Customer.Name VIEW-AS ALERT-BOX BUTTONS OK. /* ERROR raised. Control passes to CATCH block. */ FIND Order OF Customer WHERE OrderNum = 1234. /* Statement will not execute. */ DISPLAY Customer.CustNum SKIP Customer.Name SKIP OrderNum SKIP OrderStatus VIEW-AS TEXT WITH SIDE-LABELS. CATCH eSysError AS Progress.Lang.SysError: /* Confirm if Customer record is available in CATCH. */ IF AVAILABLE (Customer) THEN DO: MESSAGE "Customer record is still available." VIEW-AS ALERT-BOX BUTTONS OK. /* Re-Find the Customer to ensure buffer scoped to outer DO block has correct data for inner DO block. Cannot rely on value of TargetCustNum! */ FIND Customer WHERE Customer.CustNum = 15. /* Confirm that change to database field was not committed and UNDO variable was rolled back. */ MESSAGE "TargetCustNum = " TargetCustNum SKIP "Name is now: " Customer.Name VIEW-AS ALERT-BOX BUTTONS OK. END. /* IF */ ELSE MESSAGE "No Customer record is currently available." VIEW-AS ALERT-BOX BUTTONS OK. END CATCH. END. /* Inner DO */ END. /* Outer DO */ |