Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "EDT:Tutorial: Access a database with EGL Rich UI Lesson 6"

(New page: = Lesson 6: Add code for the service functions<br> = In EGL, I/O statements such as add and get access data that resides in different kinds of persistent data storage, from file systems t...)
 
Line 1: Line 1:
= Lesson 6: Add code for the service functions<br> =
 
  
In EGL, I/O statements such as add and get access data that resides in different kinds of persistent data storage, from file systems to queues to databases. The coding is similar for the different cases.
+
[[EDT:Tutorial: Access a database with EGL Rich UI|Access a database with EGL Rich UI]]
  
In this lesson, you add functions that access rows in a relational database. Add the functions in order, before the final end statement in SQLService.egl.<br><br>
 
  
=== Add a payment record ===
+
{| style="float: right"
 +
|[[EDT:Tutorial: RUI With DataBase Lesson 5|&lt; Previous]] | [[EDT:Tutorial: RUI With DataBase Lesson 7|Next >]]
 +
|}
 +
= Lesson 6: Add code for the service functions =
  
The addPayment() function adds a new row to the database.
+
In EGL, I/O statements such as '''add''' and '''get''' access
 +
data that resides in different kinds of persistent data storage, from
 +
file systems to queues to databases. The coding is similar for the
 +
different cases.
  
To code the function:
+
In this lesson, you add functions that access rows in
 +
a relational database. Add the functions in order, before the final '''end''' statement
 +
in SQLService.egl.
  
In the EGL editor, copy and paste the following lines into SQLService.egl before the end statement:
+
== Create binding to database connection ==
  
function addPayment(newPayment paymentRec inOut)<br> add newPayment;<br> end
+
In Lesson 3, you defined a database connection named '''Derby'''.    Use these steps to use the '''Derby'' connection from your SQL service. 
  
Before you continue, you must resolve the reference to the paymentRec Record part. You can automatically create import statements by using the Organize Imports feature. Right-click any blank area in the editor and click Organize Imports.<br> The menu contains an option for Organize Imports.<br> EGL adds the following statement to the beginning of the file:
+
#EGL projects have associated deployment descriptor ('''.egldd''') files.  Click on '''PaymentService''' in the project explorer and select '''Properties > EGLDevelopmentDeploymentDescriptor" to see that file '''PaymentService.egldd''' was created when you defined project '''Payment Service'''.  Click on '''OK''' to close the properties window.[[Image:EDT_Tutorial_edt_richui_sql06_deployment_descriptor.jpg|Deployment descriptor property for service project.]]
 +
#Open file '''PaymentService.egldd''' with the EGL employment descriptor editor.   [[Image:EDT_Tutorial_edt_richui_sql06_open_deployment_descriptor.jpg|Open deployment descriptor for service project.]]
 +
#Select the '''Resource Bindings''' folder
 +
#Add a new resource binding named '''DerbyResource''' of binding type '''SQL database binding'''.
 +
#Select radio button '''Reference the selected workspace connection below [retrieved at runtime]'''.
 +
#Select '''Derby''' connection details.
 +
#Clink on '''Finish'''.[[Image:EDT_Tutorial_edt_richui_sql05_add_sql_binding.jpg|Add SQL binding to deployment descriptor.]]
 +
#Close file '''PaymentServices.egldd'''
  
import records.paymentRec;
+
== Using an SQL resource binding in service program
  
The reference is now resolved. You will use this feature often, whether by selecting the menu item or by pressing Ctrl-Shift-O.<br> Save the file (Ctrl-S), and then place your cursor anywhere in the add statement. Right-click and select SQL Statement &gt; Add.<br> The SQL Statement options.<br> This feature changes the implicit SQL that underlies the EGL add statement into embedded code that you can modify.
+
Insert a dataSource variable in the service program following the program name:<code>
 +
  package services;
 +
 
 +
  service SQLService
 +
  ds dataSource? { @Resource { bindingKey="Derby" } } ; 
 +
  end
 +
</code>
  
The embedded SQL code<br> Because the paymentID field is auto-generated, you must not overwrite it:<br> Delete PAYMENT_ID and subsequent comma from the INSERT list.<br> Delete :newPayment.paymentId and subsequent comma from the VALUES list.<br> Note: In keeping with SQL terminology, each variable that is referenced in an SQL statement is called a host variable. The word host refers to the language that embeds the SQL statement; in this case, EGL. For example, the initial colon in :newPayment.paymentId indicates a host variable.<br> The revised add statement looks like the following image:<br> Revised SQL code<br> Save the file.
+
The syntax directs the service to use the binding named "Derby" defined as a resource in the deployment descriptor file associated with the service project.
  
Related reference
+
== Handling SQL exceptions ==
  
add considerations for SQL<br>Functions<br>import<br>SQL data access<br><br>
+
SQL operations can fail for a multitude of reasons.  For our simple example, our service will catch all SQL and log all SQL exceptions on the server and then throw the exception back to the service client.  It will also log each service invocation.
  
=== Read all database records ===
+
Cut and paste these logging function to the service program before the final '''end'' statement:<code>
 +
    logActive boolean = true;
 +
    activeService string;
 +
   
 +
    private function logEntry(serviceFunction string in)
 +
        activeService = serviceFunction;
 +
        log("Entry:  SQLService, " + serviceFunction);
 +
    end
 +
   
 +
    private function logException(ex sqlException?)
 +
        accumulatedMessage string = "Exception:  SQLService, " + activeService;
 +
        while(ex != null)
 +
            accumulatedMessage = accumulatedMessage + ", SQLSTATE = " +
 +
                    ex.SQLState + ", message = " + ex.message;
 +
            ex = ex.nextException;
 +
        end
 +
        log(accumulatedMessage);
 +
        throw new anyException{message = accumulatedMessage};
 +
    end
 +
   
 +
    private function log(text string in)
 +
        if(logActive)
 +
            sysLib.writeStdOut(text);
 +
        end
 +
    end
 +
<code/>
  
The getAllPayments function reads all of the records from the table and stores them in an array.
+
== Add a payment record ==
 +
 
 +
Include a function to the service program that uses the '''add''' statement to insert a new
 +
row to the database.  
  
 
To code the function:
 
To code the function:
  
In the EGL editor, copy and paste the following lines into SQLService.egl before the end statement:
+
#In the EGL editor, copy and paste the following lines into <tt>SQLService.egl</tt> before
 +
the '''end''' statement:<code>
 +
  function addPayment(newPayment paymentRec in)
 +
        logEntry ( "addPayment" ) ;
 +
        try
 +
            add newPayment to ds ;
 +
        onException(ex sqlException)
 +
            logException(ex);
 +
        end
 +
  end
 +
</code>
 +
#Before you continue, you must resolve the reference to
 +
the <tt>paymentRec</tt> Record part. You can automatically
 +
create '''import''' statements by using the Organize
 +
Imports feature. Right-click any blank area in the editor and click '''EGL Source > Organize
 +
Imports'''.
 +
EGL adds
 +
the following statement to the beginning of the file:<code>
 +
  import records.paymentRec;
 +
</code>
 +
The
 +
reference is now resolved. You will use this feature often, whether
 +
by selecting the menu item or by pressing Ctrl-Shift-O.
 +
#Save the file (Ctrl-S), and then place your cursor anywhere
 +
in the '''add''' statement. Press keys CTRL-1 and select '''Add SQL Statement''' from the popup menu
 +
This
 +
feature changes the implicit SQL that underlies the EGL '''add''' statement
 +
into embedded code that you can modify:<code>
 +
  add newPayment to ds with
 +
      #sql{
 +
      insert into PAYMENT
 +
      (CATEGORY, DESCRIPTION, AMOUNT, FIXED_PAYMENT, DUE_DATE,
 +
      PAYEE_NAME, PAYEE_ADDRESS1, PAYEE_ADDRESS2)
 +
      values
 +
      (?, ?, ?, ?, ?, ?, ?, ?)
 +
      } ;
 +
</code>
 +
Notice the PAYMENT_ID field is not included in the record fields added to the table.  The '''@GeneratedValue''' annotation for the field in the record definition tells the EGL SQL builder not to explicitly add the column.
  
function getAllPayments() returns (paymentRec[])<br> paymentArray paymentRec[];<br> get paymentArray;<br> return (paymentArray);<br> end
+
''' Related reference '''<br>
  
The EGL get statement generates an SQL SELECT statement to retrieve a result set. When the target of the get statement is a dynamic array of records, EGL retrieves all matching rows from the result set and inserts each successive row into the next array element.<br> Save the file.
+
[../../com.ibm.egl.lr.doc/topics/regl_data_sql_add.html add considerations for SQL]
 +
[../../com.ibm.egl.lr.doc/topics/regl_core_function.html Functions]
 +
[../../com.ibm.egl.lr.doc/topics/regl_core_import.html import]
 +
[../../com.ibm.egl.lr.doc/topics/regl_data_sql_overview.html SQL data access]
  
Related reference
+
== Read all database records ==
  
get considerations for SQL<br><br>
+
The <tt>getAllPayments</tt> function uses the get statement with an array object to read all
 +
of the records from the table and stores them in an array.
  
=== Replace a record ===
+
To
 +
code the function:
  
The editPayment function replaces an existing row in the database with an edited version. The function assumes that the user previously read the row from the database.
+
*In the EGL editor, copy and paste the following lines into <tt>SQLService.egl</tt> before
 +
the '''end''' statement:<code>
 +
  function getAllPayments() returns (paymentRec[])
 +
      paymentArray paymentRec[];
 +
      get paymentArray from ds;
 +
      return (paymentArray);
 +
  end
 +
</code>
 +
The EGL '''get''' statement generates
 +
an SQL SELECT statement to retrieve a result set. When the target
 +
of the '''get''' statement is a dynamic array
 +
of records, EGL retrieves all matching rows from the result set and
 +
inserts each successive row into the next array element.  
 +
*As with the '''statement''', you may place the cursor anywhere in the statement and press CNTL-1 to see the SQL statement EGL will use to retrieve the rows.  You may again save the default statement and modify it if it does do what you want.
 +
*Save the file.  
  
To code the function:
+
''' Related reference '''<br>
  
In the EGL editor, copy and paste the following lines into SQLService.egl before the end statement:
+
[../../com.ibm.egl.lr.doc/topics/regl_data_sql_get.html get considerations for SQL]
  
function editPayment(chgPayment paymentRec inOut)<br> replace chgPayment nocursor;<br> end
+
== Replace a record ==
  
The EGL replace statement generates an SQL UPDATE statement.<br> Save the file.
+
The <tt>editPayment</tt> function replaces an
 +
existing row in the database with an edited version. The default statement replaces all records in the table that have key values equal to the contents of the key fields in the record variable.   Key fields are those fields declared with the '''@Id''' attribute (field '''payment_id''' in our example).
  
Related reference
+
To
 +
code the function:
  
replace considerations for SQL<br><br>
+
<ol><li>In the EGL editor, copy and paste the following lines into <tt>SQLService.egl</tt> before
 +
the '''end''' statement:<code>
 +
  function editPayment(chgPayment paymentRec inOut)
 +
      replace chgPayment to ds ;
 +
  end
 +
The EGL '''replace''' statement
 +
generates an SQL UPDATE statement.
 +
<li>Save the file.
 +
</ol>
  
=== Delete a record ===
+
''' Related reference '''<br>
  
The deletePayment function deletes the specified record from the table.
+
[../../com.ibm.egl.lr.doc/topics/regl_data_sql_replace.html replace considerations for SQL]
 +
 
 +
== Delete a record ==
 +
 
 +
 
 +
 
 +
The <tt>deletePayment</tt> function deletes the
 +
specified record from the table.
  
 
To code the function:
 
To code the function:
  
In the EGL editor, copy and paste the following lines into SQLService.egl before the end statement:
+
 
 +
<ol><li>In the EGL editor, copy and paste the following lines into <tt>SQLService.egl</tt> before
 +
the '''end''' statement:  
  
 
function deletePayment(delPayment paymentRec inOut)
 
function deletePayment(delPayment paymentRec inOut)
  
try<br> delete delPayment nocursor;
+
try
 +
  delete delPayment nocursor;
  
onException(exception SQLException)<br> if(SQLLib.sqlData.sqlState != "02000") // sqlState is of type CHAR(5)<br> throw exception;<br> end<br> end<br> end
+
  onException(exception SQLException)
 +
      if(SQLLib.sqlData.sqlState != "02000") // sqlState is of type CHAR(5)
 +
        throw exception;
 +
      end
 +
  end
 +
end
 +
The EGL '''delete''' statement generates
 +
an SQL DELETE statement. If no rows are present, the Derby database
 +
returns an SQLState value of "02000", and the EGL runtime code throws
 +
an exception that the function ''catches'': that is, processes
 +
in some onException logic.
  
The EGL delete statement generates an SQL DELETE statement. If no rows are present, the Derby database returns an SQLState value of "02000", and the EGL runtime code throws an exception that the function catches: that is, processes in some onException logic.
+
When a function catches but ignores
 +
an exception, processing continues without interruption. That rule
 +
applies to the preceding logic, when the value of SQLState is "02000".
 +
When a function uses the '''throw''' statement
 +
to ''throw'' an exception, the exception stays active. That
 +
rule also applies to the preceding logic, when the value of SQLState
 +
is other than "02000".
  
When a function catches but ignores an exception, processing continues without interruption. That rule applies to the preceding logic, when the value of SQLState is "02000". When a function uses the throw statement to throw an exception, the exception stays active. That rule also applies to the preceding logic, when the value of SQLState is other than "02000".
+
At run time, if a service does not handle
 +
an exception, the service requester receives an exception of type
 +
ServiceInvocationException. Incidentally, if the service cannot be
 +
accessed, the requester receives an exception of type ServiceInvocationException
 +
or ServiceBindingException, depending on the details of the error.
  
At run time, if a service does not handle an exception, the service requester receives an exception of type ServiceInvocationException. Incidentally, if the service cannot be accessed, the requester receives an exception of type ServiceInvocationException or ServiceBindingException, depending on the details of the error.<br> Save the file.
+
<li>Save the file.
 +
</ol>
  
Related reference
+
''' Related reference '''<br>
  
delete considerations for SQL<br>Exception handling<br>
+
[../../com.ibm.egl.lr.doc/topics/regl_data_sql_delete.html delete considerations for SQL]
 +
[../../com.ibm.egl.lr.doc/topics/regl_core_xcpt.html Exception handling]
  
=== Create test data ===
+
== Create test data ==
  
The createDefaultTable function creates a set of data for testing your completed application.
 
  
To code the function:
 
  
In the EGL editor, copy and paste the following lines into SQLService.egl before the end statement:
+
The <tt>createDefaultTable</tt> function creates
 +
a set of data for testing your completed application.
 +
 
 +
To code
 +
the function:
 +
 
 +
 
 +
<ol><li>In the EGL editor, copy and paste the following lines into <tt>SQLService.egl</tt> before
 +
the '''end''' statement:  
  
 
function createDefaultTable() returns (paymentRec[])
 
function createDefaultTable() returns (paymentRec[])
  
try<br> execute #sql{<br> delete from PAYMENT<br> };
+
  try
 +
      execute #sql{
 +
        delete from PAYMENT
 +
      };
  
onException(exception SQLException)
+
  onException(exception SQLException)
  
if (SQLLib.sqlData.sqlState != "02000") // sqlState is of type CHAR(5)<br> throw exception;<br> end<br> end;
+
      if (SQLLib.sqlData.sqlState != "02000") // sqlState is of type CHAR(5)
 +
        throw exception;
 +
      end
 +
  end;
  
ispDate DATE = dateTimeLib.dateValueFromGregorian(20110405);<br> addPayment(new paymentRec{category = 1, description = "Apartment",<br> amount = 880, fixedPayment = YES});<br> addPayment(new paymentRec{category = 2, description = "Groceries",<br> amount = 450, fixedPayment = NO});<br> addPayment(new paymentRec{category = 5, description = "ISP",<br> amount = 19.99, fixedPayment = YES, dueDate = ispDate });<br> return (getAllPayments());<br> end
+
  ispDate DATE = dateTimeLib.dateValueFromGregorian(20110405);
 +
  addPayment(new paymentRec{category = 1, description = "Apartment",
 +
      amount = 880, fixedPayment = YES});
 +
addPayment(new paymentRec{category = 2, description = "Groceries",
 +
      amount = 450, fixedPayment = NO});
 +
  addPayment(new paymentRec{category = 5, description = "ISP",
 +
      amount = 19.99, fixedPayment = YES, dueDate = ispDate });
 +
  return (getAllPayments());
 +
end
  
The code acts as follows:<br> The EGL execute statement runs a literal SQL statement that deletes all rows from the PAYMENT table.<br> The ispDate variable receives a date value from the dateTimeLib.dateValueFromGregorian() system function. The content of the variable is then in a format that is appropriate for insertion into the dueDate field in the database.<br> The addPayment function is repeatedly invoked to add new rows to the PAYMENT table.<br> The call to the getAllPayments function returns an array of rows that were retrieved from the table.<br> Press Ctrl-Shift-F to format the code. If you see any red Xs, compare your code with the finished code in Finished code for SQLService.egl after lesson 6<br> Save and close the file.
+
The code acts as follows:  
  
Related reference
+
<ul><li>The EGL '''execute''' statement runs a literal
 +
SQL statement that deletes all rows from the PAYMENT table.
 +
<li>The <tt>ispDate</tt> variable receives a date value from
 +
the '''dateTimeLib.dateValueFromGregorian()''' system
 +
function. The content of the variable is then in a format that is
 +
appropriate for insertion into the <tt>dueDate</tt> field
 +
in the database.
 +
<li>The <tt>addPayment</tt> function is repeatedly invoked
 +
to add new rows to the PAYMENT table.
 +
<li>The call to the <tt>getAllPayments</tt> function returns
 +
an array of rows that were retrieved from the table.
 +
</ul>
  
execute considerations for SQL<br>dateValueFromGregorian()<br>
+
<li>Press Ctrl-Shift-F to format the code. If
 +
you see any red Xs, compare your code with the finished code in [[EDT:Tutorial: RUI With DataBase Lesson 6 Code|Code for PaymentFileMaintenance.egl after lesson 6]]
 +
<li>Save and close the file.
 +
</ol>
  
=== Lesson checkpoint ===
+
''' Related reference '''<br>
 +
 
 +
[../../com.ibm.egl.lr.doc/topics/regl_data_sql_execute.html execute considerations for SQL]
 +
[../../com.ibm.egl.lr.doc/topics/regl_core_date_date_value_greg.html dateValueFromGregorian()]
 +
 
 +
== Lesson checkpoint ==
  
 
You learned how to complete the following tasks:
 
You learned how to complete the following tasks:
  
*Add embedded SQL code to a program and modify that code
+
<ul><li>Add embedded SQL code to a program and modify that code
*Automatically create and organize import statements
+
<li>Automatically create and organize '''import''' statements
 +
</ul>
 +
 
 +
In the next lesson, you will create a widget to hold the table
 +
of expense data.
 +
 
 +
 
 +
 
 +
{| style="float: right"
 +
|[[EDT:Tutorial: RUI With DataBase Lesson 5|&lt; Previous]] | [[EDT:Tutorial: RUI With DataBase Lesson 7|Next >]]
 +
|}
  
In the next lesson, you will create a widget to hold the table of expense data.
 
  
<br>
+
[[Category:EDT]]

Revision as of 15:48, 29 November 2011

Access a database with EGL Rich UI


< Previous | Next >

Lesson 6: Add code for the service functions

In EGL, I/O statements such as add and get access data that resides in different kinds of persistent data storage, from file systems to queues to databases. The coding is similar for the different cases.

In this lesson, you add functions that access rows in a relational database. Add the functions in order, before the final end statement in SQLService.egl.

Create binding to database connection

In Lesson 3, you defined a database connection named Derby'. Use these steps to use the Derby connection from your SQL service.

  1. EGL projects have associated deployment descriptor (.egldd) files. Click on PaymentService in the project explorer and select Properties > EGLDevelopmentDeploymentDescriptor" to see that file PaymentService.egldd was created when you defined project Payment Service. Click on OK to close the properties window.Deployment descriptor property for service project.
  2. Open file PaymentService.egldd with the EGL employment descriptor editor. Open deployment descriptor for service project.
  3. Select the Resource Bindings folder
  4. Add a new resource binding named DerbyResource of binding type SQL database binding.
  5. Select radio button Reference the selected workspace connection below [retrieved at runtime].
  6. Select Derby connection details.
  7. Clink on Finish.Add SQL binding to deployment descriptor.
  8. Close file PaymentServices.egldd

== Using an SQL resource binding in service program

Insert a dataSource variable in the service program following the program name:

  package services;
  
  service SQLService
  	ds dataSource? { @Resource { bindingKey="Derby" } } ;   
  end

The syntax directs the service to use the binding named "Derby" defined as a resource in the deployment descriptor file associated with the service project.

Handling SQL exceptions

SQL operations can fail for a multitude of reasons. For our simple example, our service will catch all SQL and log all SQL exceptions on the server and then throw the exception back to the service client. It will also log each service invocation.

Cut and paste these logging function to the service program before the final 'end statement:

    logActive boolean = true;
    activeService string;
    
    private function logEntry(serviceFunction string in)
        activeService = serviceFunction;
        log("Entry:  SQLService, " + serviceFunction);
    end
    
    private function logException(ex sqlException?)
        accumulatedMessage string = "Exception:  SQLService, " + activeService;
        while(ex != null)
            accumulatedMessage = accumulatedMessage + ", SQLSTATE = " +
                    ex.SQLState + ", message = " + ex.message;
            ex = ex.nextException;
        end
        log(accumulatedMessage);
        throw new anyException{message = accumulatedMessage};
    end
    
    private function log(text string in)
        if(logActive)
            sysLib.writeStdOut(text);
        end
    end

<code/>

Add a payment record

Include a function to the service program that uses the add statement to insert a new row to the database.

To code the function:

  1. In the EGL editor, copy and paste the following lines into SQLService.egl before

the end statement:<code>

  function addPayment(newPayment paymentRec in)
       logEntry ( "addPayment" ) ;
       try
           add newPayment to ds ;
       onException(ex sqlException)
           logException(ex);
       end
  end

  1. Before you continue, you must resolve the reference to

the paymentRec Record part. You can automatically create import statements by using the Organize Imports feature. Right-click any blank area in the editor and click EGL Source > Organize Imports. EGL adds the following statement to the beginning of the file:

  import records.paymentRec;

The reference is now resolved. You will use this feature often, whether by selecting the menu item or by pressing Ctrl-Shift-O.

  1. Save the file (Ctrl-S), and then place your cursor anywhere

in the add statement. Press keys CTRL-1 and select Add SQL Statement from the popup menu This feature changes the implicit SQL that underlies the EGL add statement into embedded code that you can modify:

  add newPayment to ds with
     #sql{ 
     	insert into PAYMENT
     		(CATEGORY, DESCRIPTION, AMOUNT, FIXED_PAYMENT, DUE_DATE, 
     		PAYEE_NAME, PAYEE_ADDRESS1, PAYEE_ADDRESS2)
     	values
     		(?, ?, ?, ?, ?, ?, ?, ?)
     } ;

Notice the PAYMENT_ID field is not included in the record fields added to the table. The @GeneratedValue annotation for the field in the record definition tells the EGL SQL builder not to explicitly add the column.

Related reference

[../../com.ibm.egl.lr.doc/topics/regl_data_sql_add.html add considerations for SQL] [../../com.ibm.egl.lr.doc/topics/regl_core_function.html Functions] [../../com.ibm.egl.lr.doc/topics/regl_core_import.html import] [../../com.ibm.egl.lr.doc/topics/regl_data_sql_overview.html SQL data access]

Read all database records

The getAllPayments function uses the get statement with an array object to read all of the records from the table and stores them in an array.

To code the function:

  • In the EGL editor, copy and paste the following lines into SQLService.egl before

the end statement:

  function getAllPayments() returns (paymentRec[])
     paymentArray paymentRec[];
     get paymentArray from ds;
     return (paymentArray);
  end

The EGL get statement generates an SQL SELECT statement to retrieve a result set. When the target of the get statement is a dynamic array of records, EGL retrieves all matching rows from the result set and inserts each successive row into the next array element.

  • As with the statement, you may place the cursor anywhere in the statement and press CNTL-1 to see the SQL statement EGL will use to retrieve the rows. You may again save the default statement and modify it if it does do what you want.
  • Save the file.

Related reference

[../../com.ibm.egl.lr.doc/topics/regl_data_sql_get.html get considerations for SQL]

Replace a record

The editPayment function replaces an existing row in the database with an edited version. The default statement replaces all records in the table that have key values equal to the contents of the key fields in the record variable. Key fields are those fields declared with the @Id attribute (field payment_id in our example).

To code the function:

  1. In the EGL editor, copy and paste the following lines into SQLService.egl before the end statement: function editPayment(chgPayment paymentRec inOut) replace chgPayment to ds ; end The EGL replace statement generates an SQL UPDATE statement.
  2. Save the file. </ol> Related reference
    [../../com.ibm.egl.lr.doc/topics/regl_data_sql_replace.html replace considerations for SQL]

    Delete a record

    The deletePayment function deletes the specified record from the table.

    To code the function:


    1. In the EGL editor, copy and paste the following lines into SQLService.egl before the end statement: function deletePayment(delPayment paymentRec inOut) try delete delPayment nocursor; onException(exception SQLException) if(SQLLib.sqlData.sqlState != "02000") // sqlState is of type CHAR(5) throw exception; end end end The EGL delete statement generates an SQL DELETE statement. If no rows are present, the Derby database returns an SQLState value of "02000", and the EGL runtime code throws an exception that the function catches: that is, processes in some onException logic. When a function catches but ignores an exception, processing continues without interruption. That rule applies to the preceding logic, when the value of SQLState is "02000". When a function uses the throw statement to throw an exception, the exception stays active. That rule also applies to the preceding logic, when the value of SQLState is other than "02000". At run time, if a service does not handle an exception, the service requester receives an exception of type ServiceInvocationException. Incidentally, if the service cannot be accessed, the requester receives an exception of type ServiceInvocationException or ServiceBindingException, depending on the details of the error.
    2. Save the file.

    Related reference

    [../../com.ibm.egl.lr.doc/topics/regl_data_sql_delete.html delete considerations for SQL] [../../com.ibm.egl.lr.doc/topics/regl_core_xcpt.html Exception handling]

    Create test data

    The createDefaultTable function creates a set of data for testing your completed application.

    To code the function:


    1. In the EGL editor, copy and paste the following lines into SQLService.egl before the end statement: function createDefaultTable() returns (paymentRec[]) try execute #sql{ delete from PAYMENT }; onException(exception SQLException) if (SQLLib.sqlData.sqlState != "02000") // sqlState is of type CHAR(5) throw exception; end end; ispDate DATE = dateTimeLib.dateValueFromGregorian(20110405); addPayment(new paymentRec{category = 1, description = "Apartment", amount = 880, fixedPayment = YES}); addPayment(new paymentRec{category = 2, description = "Groceries", amount = 450, fixedPayment = NO}); addPayment(new paymentRec{category = 5, description = "ISP", amount = 19.99, fixedPayment = YES, dueDate = ispDate }); return (getAllPayments()); end The code acts as follows:
      • The EGL execute statement runs a literal SQL statement that deletes all rows from the PAYMENT table.
      • The ispDate variable receives a date value from the dateTimeLib.dateValueFromGregorian() system function. The content of the variable is then in a format that is appropriate for insertion into the dueDate field in the database.
      • The addPayment function is repeatedly invoked to add new rows to the PAYMENT table.
      • The call to the getAllPayments function returns an array of rows that were retrieved from the table.
    2. Press Ctrl-Shift-F to format the code. If you see any red Xs, compare your code with the finished code in Code for PaymentFileMaintenance.egl after lesson 6
    3. Save and close the file.

    Related reference

    [../../com.ibm.egl.lr.doc/topics/regl_data_sql_execute.html execute considerations for SQL] [../../com.ibm.egl.lr.doc/topics/regl_core_date_date_value_greg.html dateValueFromGregorian()]

    Lesson checkpoint

    You learned how to complete the following tasks:

    • Add embedded SQL code to a program and modify that code
    • Automatically create and organize import statements

    In the next lesson, you will create a widget to hold the table of expense data.


    < Previous | Next >

Back to the top