Application Development Considerations The decisions related to how to create and organize your application within the APEX and database environment will greatly affect how easily you’l
Trang 2and Contents at a Glance links to access them
Trang 3iv
Contents at a Glance
About the Authors xv
About the Technical Reviewer xvii
Acknowledgments xviii
Foreword xix
Introduction xxi
Chapter 1: Development Best Practices 1
Chapter 2: Authentication and User Management 41
Chapter 3: Conditions and Authorization Schemes 101
Chapter 4: Data Security 137
Chapter 5: Navigation and Layout 187
Chapter 6: Reports and Charts 241
Chapter 7: Dynamic Actions 299
Chapter 8: Websheets 331
Chapter 9: Reporting and Printing 367
Chapter 10: Themes and Templates 409
Chapter 11: Localization Issues 455
Chapter 12: Plug-ins 495
Chapter 13: Web Services 527
Chapter 14: Performance and Scalability 559
Chapter 15: Production Issues 599
Chapter 16: APEX Dictionary 647
Index 689
Trang 4xxi
If you’re new to APEX development, prepare yourself for one of the most productive tools available for Oracle application development The speed with which you can create fully functional, secure, web-
based applications is truly astounding, especially when compared to using a tool like Java If you are
used to writing procedural or object-oriented code, you may find APEX’s declarative development
methodology a little challenging at first, but the learning curve is not significant When you consider
that you only need an Oracle database to get started, the barriers to beginning APEX development are
minimal
The first edition of this book, Pro Oracle Application Express, was written in 2008 using APEX
3.2 In 2010, Oracle released APEX 4.0, which included a significant number of new features along with a major upgrade of the development environment’s user interface Along with the much improved look and feel, Oracle included several Web 2.0 features like Dynamic Actions, Plug-ins, and RESTFul web
service support Prior to APEX 4.0, you could implement the newest web features, but it usually required custom coding With APEX 4.0, you can use the familiar declarative development techniques to add an Ajax feature, for example The inclusion of these significant new features obviated the need for a
revision of the original book
In general, APEX 4.0 lets you create professional looking, feature-laden applications with less
effort than ever before
Trang 5
Development Best Practices
Oracle Application Express (APEX) makes it extremely easy to quickly prototype and develop a web
application However, as a software developer, you’re probably aware that speed of development is only one of a number of criteria that will contribute to the perceived success (or failure) of your project
Of course, perceptions about a project’s success can vary For example, the people who encounter a typical project might include developers, testers, managers, production support, and end users The
developers may feel that the project was a success because development went quickly, Production
support might feel like the project was a failure because no one has a clear strategy for performing
application upgrades The end users may dread using the application because it runs incredibly slowly Clearly, for the project to be considered a success, you need to satisfy the expectations of all these people (or as many as you reasonably can) Ideally, you should strive for an application that has the following
characteristics:
• Easy to develop
• Easy to deploy and upgrade
• Easy to maintain and debug
• Enjoyable for end users to use
• Fast enough for the users’ requirements
• Stable from the end users’ perspective
• Secure enough to protect your data from unauthorized access
You should never end up feeling like developing, deploying, maintaining, or (even worse) using the application is seen as a chore Each of these areas can often benefit from the adoption of some best
practices to ensure that everyone involved sees your application as a success
Chapter 1 is the best place to introduce best-practice techniques, since they should form the
foundation of every significant development project you undertake You can certainly create
applications without using any of the techniques we’ll discuss, but adopting techniques like these will
make your job as a developer easier, and your applications will be considerably more successful
Trang 6APEX Installation Decisions
This book will not cover the details of installing APEX version 4.0, since that information is already bundled with the product, as well as discussed in detail in several online resources It is worth
mentioning, however, that APEX 4.0 supports another connection type via the Oracle Application Express Listener The APEX Listener is a Java-based web server that is certified to run under Web Logic, Tomcat, OC4J with Oracle WebLogic Server, OC4J, and Oracle Glassfish
Indeed, many people enjoy using APEX without bothering with installation, either because someone else has installed it for them or they are using a hosted environment (such as the public Oracle
apex.oracle.com site or one of the commercial providers such as Shellprompt) Others use Oracle
Database Express Edition (XE), a free edition of the database that includes a preinstalled version of APEX
However, if you are installing APEX, one important decision is which tablespace to use for the
product The installer usually defaults to installing APEX into the SYSAUX tablespace, and if you’re using
the 11g version of the database, the SYSAUX tablespace will be selected by default I highly recommend
that instead of using SYSAUX you create a dedicated tablespace that you’ll use specifically for the APEX
database objects and metadata By using a dedicated tablespace, you can gain a far greater degree of control and flexibility over the administration of the APEX environment For example, should it become necessary to recover the tablespace using point-in-time recovery from an Oracle Recovery Manager (RMAN) backup, you’ll be confident that you haven’t affected any other database components, like AWR
(which may not be the case if you install into SYSAUX)
Installing into a separate, dedicated tablespace also allows the database administrator (DBA) to make decisions about where that dedicated tablespace should be stored on disk (to reduce contention), control the storage growth of the tablespace, and perhaps also take advantage of advanced Oracle features, such as transportable tablespaces to quickly move the tablespace to another database instance
Application Development Considerations
The decisions related to how to create and organize your application within the APEX and database environment will greatly affect how easily you’ll be able to deploy and migrate your application later on
By structuring your development environment in a logical and organized way, you’ll encounter far fewer problems when your application needs to be deployed or updated to your live environment
Users and Administrators
When APEX is installed, an Application Express instance administrator is created You can connect to APEX as this instance administrator in two ways:
• Connect to one of the following URL’s:
• PL/SQL Plugin: http://server:port/pls/apex/apex_admin
• APEX Listener or EPG: http://server:port/apex/apex_admin
Use the username ADMIN and the password you used when you installed the product
Trang 7• Connect to the same URL you’d use to log into any workspace, such as
http://server:port/pls/apex/apex_login, and use INTERNAL as the workspace and ADMIN as the
username with the password you used when you installed the product
Including the instance administrator, four different types of users exist for APEX:
Application Express instance administrator: This is the user you’ll use to
administer the APEX installation The instance administrator can connect only
to the INTERNAL workspace to perform administration tasks, such as creating
workspaces and users, monitoring activity, and managing the APEX service
Instance administrators can’t create any applications themselves; they must
create workspaces and other users for applications to be created The instance
administrator can create workspace administrators, developers, and built-in
users for any of the workspaces
Workspace administrator: A workspace administrator is responsible for the
administration of a particular workspace As a workspace administrator, you
are able to create developers and users for that workspace, and create
applications Workspace administrators can also log into any application within
the same workspace that uses APEX account credentials
Application developer: Application developers are created within a particular
workspace by workspace administrators They can create and maintain an
application within that workspace They can’t log in to other workspaces, but they
are able to log in to any application within the same workspace that uses APEX
account credentials
Application user: Application users can take two forms They can be created and
managed within the APEX environment and are then known as built-in users
(or cookie users) Alternatively, they can be created and managed outside the
APEX environment; for example, they could be stored within a database table or
as part of a Lightweight Directory Access Protocol (LDAP) directory Built-in
users are able to log in to any application within the same workspace that uses
APEX account credentials
For small projects with a single developer, it is quite possible to perform all
application development as the workspace administrator However, for any
development that uses two or more developers, it’s best to create a specific
developer account for each physical developer, since this lets you use features
such as page-locking, as well as track changes to the application at the
developer level
Although the workspace administrator could be one of the physical developers, a better idea is to
create a developer account to use for development Use the workspace administrator account only when necessary to perform administration duties
Workspaces and Schemas
When you create an application in APEX, you must select a schema as the default parsing schema In
other words, if you built a report that issued a query like this:
Trang 8select empno, ename from emp;
the query would use the emp table in the schema you selected as the parsing schema when you created
your application If you wanted to access an object in a different schema, you could prefix the object name with the schema name, like this:
select empno, ename from payroll.emp;
Because the application will be executed using the parsing schema (and its privileges), accessing objects in other schemas requires that the appropriate privileges are granted to the parsing schema Objects in other schemas can also be accessed via synonyms or a view, which effectively hides the schema and enables you to reference the object without needing to specify the schema name yourself
Choosing a Parsing Schema
The schemas assigned to the workspace you are currently logged into define the choice of schemas that can be used as the parsing schema When you create a workspace (as an APEX administrator), you must specify whether to use an existing schema or create a new one, as shown in Figure 1-1 If no other schemas are assigned to the workspace, you will be able to select only this schema as the parsing schema when you create your application
Figure 1-1 Creating a new workspace
This means that if you already have an existing schema with a lot of objects you’d like to access, you can select that schema Then, any applications that are created within the schema will be able to access those schema objects directly This way, you can create an application in APEX that provides a front end
to existing data very quickly
Although you can select only a single schema during the provisioning of the workspace, extra schemas can be assigned to the schema later on After these additional schemas have been assigned to the workspace, they are available to workspace developers to use as the default parsing schema when they create an application within that workspace
If you choose to create a new schema during the provisioning of the workspace, a new tablespace and corresponding datafile will be created for that schema automatically The disadvantage is that the
tablespace and datafile will have nondescriptive names, such as APEX_1400423609989676 and
APEX_1400423609989676.dbf Moreover, if you later decide to remove the workspace, that tablespace and
datafile will not be deleted If you regularly provision and delete a lot of workspaces, you can end up with
Trang 9many tablespaces and datafiles cluttering up your disk (and perhaps being unnecessarily included in
your backups)
For small developments or evaluation, it may be fine to create a new schema through the APEX
wizard However, from a maintenance point of view, this approach often increases the difficulty in
correlating schemas, tablespaces, datafiles, and workspaces because of the nondescriptive names While this may not be a primary concern to you as a developer, it can be critical to how quickly the DBA is able
to restore your schema from a backup if necessary
Generally, for larger developments, if you are not using an existing schema, you may
find it beneficial to manually create the tablespace and schema yourself, using a tool such as Enterprise
Manager For example, you can create a tablespace called APEXDEMO, which has a single datafile named
APEXDEMO01.dbf that’s allowed to grow to 2GB You can then create a user APEXDEMO that has the APEXDEMO
tablespace as its default tablespace Figure 1-2 shows how the schema would look after being created in Enterprise Manager
Figure 1-2 Creating a schema in Enterprise Manager
You could now create a workspace named APEXDEMO and select the APEXDEMO schema you just created
in Enterprise Manager, as shown in Figure 1-3 This naming scheme ties together your workspace with
the underlying schema and related tablespace and datafiles If you should accidentally drop some tables
(forgetting for the moment about the recycle bin in Oracle Database 10g / 11g), you can use RMAN to
recover them easily, since their schema and tablespace will be obvious
Figure 1-3 Creating a workspace using an existing schema
Although the APEX administrator can view reports that show which schemas and tablespaces
particular workspaces are using, adopting a sensible naming convention makes it easier to get this
information For example, the DBA could look at a tablespace called APEXDEMO and be able to understand
the purpose of that tablespace, which would not be clear from a generic tablespace name like
APEX_1400423609989676
Trang 10 Note Naming and coding standards can be extremely subjective For example, some people may prefer to name the tablespace as APEXDEMO_TS while others prefer TS_APEXDEMO If you already have an existing policy that details how you should name database objects, it makes sense to adopt that same policy for your development with APEX If you do not currently have a policy in place, you should consider adopting one The standards policy you use should be detailed enough to aid you in your work, but not so draconian that it actually hinders you
Once the workspace is provisioned, additional schemas can be assigned to it For example, you can
create an APEXDEMO_TEST schema in Enterprise Manager, log in as the Application Express instance
administrator, choose Manage WorkspacesManage Workspace to Schema Assignments, and select that schema, as shown in Figure 1-4
Figure 1-4 Adding a schema to a workspace
Controlling Access to New Schemas
Now the workspace administrator can specify which application developers can use the new schema (or, indeed, any of the assigned schemas) Figure 1-5 shows an example of a new developer account being
created By default, the developer will be able to access both schemas (APEXDEMO and APEXDEMO_TEST),
since both schemas have been assigned to this workspace
Trang 11Figure 1-5 Creating a new developer with access to all assigned schemas
When this developer logs into the workspace, he or she can see the list of schemas that are available
by clicking on the AdministrationManage Instance menus, as shown in Figure 1-6 Any application this developer creates can use any of the available schemas as its default parsing schema, as shown in
Figure 1-7
Trang 12Figure 1-6 Schemas available to the developer
Figure 1-7 Selecting a default parsing schema for an application
Trang 13It is possible, using multiple schemas assigned to a workspace, to establish a
development/testing/live environment all within the same workspace For example, you could create a single workspace that has a schema for development, a schema for testing, and a schema for live objects and data You could then have three copies of your application: one pointing to the development
schema, one to the testing schema, and one to the live schema However, with this approach, it is all too easy to become confused about which schema you are operating in, with potentially disastrous effects
It’s best to create separate workspaces for development, testing, and live environments This forces you to specifically log in to an environment, and helps to minimize the risk of making application or
schema changes in the wrong environment The APEX environment helpfully displays which workspace you are logged in to (and which user you are logged in as), so it definitely pays to double-check this
information before you perform any drastic operations
You also need to consider how the development, testing, and production environments will be
staged You may have each environment running on a different database instance (for example, a
development instance, a testing instance, and a production instance) If you have only one database
instance, it is possible to have the three (or two if you choose to forgo the testing environment!)
environments all installed on the same database instance
Application Deployment
An APEX application consists of three main components:
• The APEX application itself
• Any external images and files (such as CSS files), stored in the web server file
system
• Database objects and data contained in the schema
The definition of the application itself—that is, the metadata that represents the pages, branches,
processing logic, and so on—is stored in the schema that was created when the product was installed
This is quite distinct from the database objects on which your application performs operations, which
are the database objects that reside in the parsing schema of your application and any other schemas
that your application accesses
In order to deploy your application from one database to another (where APEX has already been
installed), you need to deploy the application definition as well as any database objects on which it is
depends You also need to deploy any static files (CSS files, images, and so on)
Deploying Workspaces
When moving an application from one APEX instance to another (instance here refers to a database with
the APEX software installed), you need to have created the workspace on the destination instance The
instance administrator can choose to either create the workspace manually or export the existing
workspace from the source instance Exporting the workspace creates a file containing the SQL needed
to re-create that workspace, and the instance administrator can then import that SQL file to the
Trang 14destination instance Figure 1-8 shows the APEXDEMO workspace being exported Note that you can
specify a file format to use (either UNIX or DOS), which will determine the newline sequence used in the file
Figure 1-8 Exporting a workspace
The advantage of using a workspace export file is that this also re-creates all the users and
developers created within that workspace, so it’s a quick way of migrating all the existing users (and their permissions) to a new server It also demonstrates an advantage of using the built-in users If you use another method to authenticate your users, you’ll need to handle their migration manually Listing 1-1
shows the contents of the file that is created by exporting the APEXDEMO workspace
Listing 1-1 Contents of a Workspace Export File
set serveroutput on size 1000000
set feedback off
Company, user group and user export
Creating a workspace will not create database schemas or objects
This API will cause only meta data inserts
prompt Creating workspace APEXDEMO
Trang 16 Note Since the export file is a series of Data Definition Language (DDL) statements, it can be edited, such as
to change the name of the workspace However, you really shouldn’t do this unless you have been specifically advised to do so by Oracle
Deploying Applications
An application developer (or workspace administrator) can export an application from the Application Builder interface This creates a file similar to the workspace export file, in that the file will contain all the statements necessary to create the metadata required for the application However, the application export file does not contain the DDL to create any of the database objects your application uses, nor does the application export file contain any data from the database objects that your application uses Such data would normally be handled with specialized data-loading tools, such as the import and export utilities, or copied over a database link
You can use the APEX export options, shown in Figure 1-9, to affect the file that is created For the most part, you won’t need to change application export settings However, you should understand what each of these options do Here are descriptions of some of the more useful options:
File Format: This allows you to specify whether you want to use a DOS or UNIX format Your choice
will affect which newline sequences will be used in the resulting export file
Owner Override: This lets the owner of an application specify that a different schema should be used
rather than the one that is currently specified It allows you to import the schema into a workspace that’s completely different from the workspace from which the application was exported
Build Status Override: This lets you specify whether the resulting export file will contain an
application that developers can access (Run and Build Application) or one that only end users can access (Run Application Only)
As of minutes ago: This allows you to export an application as it existed some time ago For
example, you could export an application the way it was before you deleted a page
Export Preferences: This set of options is new in APEX 4.0 and allows for some additional control
during the export process
Trang 17Figure 1-9 Exporting an application
An important consideration is whether you want developers to be able to access your application
when it is imported to the target server There is a trade-off between the added security you gain by
exporting the application as Run Application Only versus not allowing your developers to access and
debug the application via the Application Builder
When you set an application to Run Application Only, you lose the ability to debug (by changing the NO
in the URL to YES) and trace that application (by adding p_trace=YES to the URL) Generally, you want to set
your production applications to Run Application Only, so that end users can’t gain direct access to debug
information that they shouldn’t be able to see
Deploying Static Files
APEX applications can include references to many different types of static files, including Cascading
Style Sheets (CSS), images (JPG, GIF, and so on), JavaScript libraries, and Flash movies You can
reference these static files in two ways:
• They can be stored on a file system that’s accessible by the Oracle HTTP Server
(OHS)
• They can be uploaded to the database via the Application Builder interface
Both methods have advantages and disadvantages, and you should be aware of how each method
will affect your application Whether you choose to store files in the file system or in the database
Trang 18ultimately comes down to how you intend to manage those files and whether they need to be used by other external systems
Uploading Static Files to the Database
You can upload static files to the database simply by using a browser This means that you can upload a new image to the database and use it in your application immediately, without needing to involve the person in charge of administering the web server When you reference these static files in your
application, they are actually downloaded to the end user’s browser via a database procedure For
example, if you uploaded a static file called logo.jpg, you could reference that file in an HTML region in
your application with the following line of code:
<img src="#WORKSPACE_IMAGES#logo.jpg"></img>
When that HTML region is processed, the #WORKSPACE_IMAGES# directive will be translated into
something like this:
<img src="wwv_flow_file_mgr.get_file?p_security_group_id=16&p_fname=logo.jpg"></img>
Note In the example, the value used for p_security_group_id is modified so that it fits onto a single line on this book page In reality, you would have a number such as 1635127392255802
Any static files you reference in this way will be downloaded to the end user’s browser as a result of
making a call to the get_file routine This approach has two downsides:
• Each file you reference in this way requires a separate call to the get_file routine
• Quite often, browsers fail to store the image in their cache In these cases, the
static file will be rerequested every time the page is displayed, resulting in loading pages and images that appear to flicker as they reload
slower-You can write your own get_file replacement procedure to enable the browser to cache the static
files, as you’ll learn in Chapter 9
Storing Static Files on the Server File System
Storing files directly in the web server file system usually makes caching the static files happen
transparently, since the OHS can add some default expiry headers to the file as it is requested by the user’s browser When the user views the same page again, his browser determines whether the image can be reloaded from the browser cache or if it needs to be requested again from the web server By taking advantage of caching for static files, your application will appear far more responsive to your end users, as well as put less load on your database
The downside of storing static files directly in the file system is that they aren’t as integrated with your application For example, you’ll need to ensure that they are backed up as a separate process, since they won’t be backed up as part of the database You also need to ensure that the file names on the file system correspond to the names you used to reference the files in your application
Trang 19Application Portability and Code Reuse
APEX offers several features to make your application more portable between environments We’ll look
at a few of these features, as well as how to separate data and application logic from style and
presentation
Using Substitution Strings to Avoid Hard-Coding References
Every application in APEX has a unique identifier—an application ID—assigned to it This ID is used to
identify the application and the associated metadata within the APEX repository
When you move applications between different APEX environments, such as between your
development and test environments, you might encounter problems if you’ve hard-coded any
references to values that may be different in these environments Unless you can be absolutely certain
that the application ID and any other references are exactly the same in the different environments, you shouldn’t hard-code any of these references
You can avoid hard-coding the application ID by using the APP_ID substitution string Here’s an
example of a typical URL where the application ID (112) has been hard-coded:
f?p=112:1:&APP_SESSION.:
If you import your application into an APEX environment that already has an application that uses the same application ID, forcing you to use a different ID, you may forget to update your hard-coded
references In that case, your links will point to the wrong application
To avoid this, you should use the APP_ID substitution string, which will be replaced with the actual
ID of your application at runtime Using this substitution string, the URL now looks like this:
f?p=&APP_ID.:1:&APP_SESSION.:
This makes your application more portable between APEX environments
Although it is not common for pages to be renumbered, you can also avoid having to hard-code a
page ID by using the APP_PAGE_ID substitution string This can be useful where you have a branch on a
page that branches back to the same page
A page within an application can also have an alias defined for it For example, you may give page 1
the alias of HOME, as shown in Figure 1-10 Now, rather than using a URL such as this:
f?p=&APP_ID.:1:&APP_SESSION.:
you can use this URL:
f?p=&APP_ID.:HOME:&APP_SESSION.:
Trang 20Figure 1-10 Defining an alias for the page
By using the alias in the reference, you’ll be able to renumber the pages and the URL will still be pointing to the correct page
You should use substitution strings to avoid hard-coding any references to resources (such as style sheets) in templates and HTML regions This will give you great flexibility to change the location of those resources, whether they are uploaded into the database or are stored in the file system For example, if you stored all your images in the database by uploading them through the Application Builder interface, you might refer to a particular image file like this:
<img src="#APP_IMAGES#logo.gif" type="image/jpeg" />
At runtime, this will be expanded to reference the download procedure that is used for accessing static files that have been uploaded into the database The text that is substituted at runtime will be something like this:
wwv_flow_file_mgr.get_file?p_security_group_id=986113558690831&p_flow_id=112&p_fname
=logo.gif
In this section, I described #WORKSPACE_IMAGES# and #APP_IMAGES# The simple difference between
the two is that workspace images are available to any application in a workspace while application images are available only in the application to which they’re assigned If you want to assign an image to
an application, you specify the application name during the upload process If you don’t specify an app name, the image will be available to all applications in the workspace
However, if you now wanted to store the images in the file system rather than in the database, you’d need to change every reference like this one to use a different path to the file
To simplify and minimize the number of changes you’ll need to make, you can define a substitution
string that will be used in place of the #APP_IMAGES# substitution string You can find the Substitution
Strings section on the Application Definition page in the Shared Components part of the Application
Builder, as shown in Figure 1-11 When you define the substitution string IMAGE_PATH for the value
#APP_IMAGES#, the URL then looks like this:
<link rel="stylesheet" href="&IMAGE_PATH.logo.gif" type="text/css" />
Trang 21Figure 1-11 Defining the alias to reference the #APP_IMAGES# substitution string
Effectively, this creates a substitution string that references a substitution string At runtime, this
will be expanded to reference the same download procedure that was used before The advantage of
using this technique is that if you later decide to store the static files in the file system, rather than
storing them within the database, you can simply change the value of your substitution string to reflect
the new location, Figure 1-12 shows the substitution string modified to use a reference to the file system instead
Figure 1-12 Changing the substitution string value to use the file system
This greatly reduces the number of references you’ll need to change when moving your application between different APEX environments where the static files are stored in different locations, Figure 1-13 shows how the substitution string would be set in the development environment
Figure 1-13 Substitution string set in the development environment
Using the Publish/Subscribe Feature
The publish/subscribe feature allows you to reuse certain common components among applications
You can define your component in an application, and then other applications can reference that
common component by subscribing to it Any changes that are made to the master component can then easily be incorporated into the applications that subscribe to the component
Changes can be propagated from the master component to the subscribing component in two ways:
From the master component: The master component publishes the changes to all subscribing
applications If you want the changes to the master component to be reflected in all subscribing
components, you publish the changes from the master component
Trang 22From within applications: The subscribing applications refresh the components that subscribe to a
master component If you want only certain applications to have their subscribing componentsupdated, you refresh the components from within those applications
The following components can make use of the publish/subscribe feature:
select ename d, empno r
from emp
order by 1
Figure 1-14 shows the results of using this LOV in a select list
Figure 1-14 Using the master LOV in a select list
Trang 23In another application within the same workspace, you can create a new LOV and choose to create it based on an existing LOV, as shown in Figure 1-15 The LOV creation wizard will then allow you to select which application (in the same workspace) should be used to list the available LOVs to subscribe to, as
shown in Figure 1-16
Figure 1-15 Creating an LOV that will subscribe to the master LOV
Figure 1-16 Copying the LOV from the master application
Once you’ve selected an application, the LOVs available in that application will be displayed, as
shown in Figure 1-17, allowing you to copy and subscribe to them
Figure 1-17 Subscribing to the master LOV
Trang 24If you now create a select list in the application that uses the LOV you’ve subscribed to, you will see the same list of employees displayed in the master application, as shown in Figure 1-18
Figure 1-18 A select list based on the subscribing LOV
If you decide you want to change the definition of the LOV so that the employees are listed in descending alphabetical order, you can go back to the master application and change the query as follows:
select ename d, empno r
from emp
order by 1 desc
At this point, the master application would display the employees in descending alphabetical order, while the application that subscribes to the LOV would still display the employees in ascending order To update the subscribing LOV, you need to either publish the changes from the LOV in the master
application, as shown in Figure 1-19, or refresh the LOV in the subscribing application, as shown in Figure 1-20
Figure 1-19 Publishing the changes from the master LOV
Trang 25Figure 1-20 Refreshing the subscribing LOV
After you either publish the changes from the master application or refresh the subscribing LOV, the select list in the application will use exactly the same query that was defined in the master application
Figure 1-21 shows the select list now displaying the employees in descending alphabetical order
Figure 1-21 Subscribing LOV refreshed with the master LOV
The publish/subscribe functionality makes it far easier to maintain consistent appearance and
behavior across common applications You could create a single application that’s used as the master for all of your common applications, and then make changes to the common components in the master
application and synchronize the changes to the other applications by publishing from the master
application or refreshing from individual applications
Separating Data and Application Logic from Style and Presentation
To ensure that your applications and code are as portable and reusable as possible, you should strive to
keep the data itself distinct from its presentation This means that in general you shouldn’t embed HTML
markup into the data-retrieval process For example, suppose you want to display employee names in bold
in a report You could use a query like this:
select '<b>' || ename || '</b>' as ename, deptno, sal from emp
However, it’s better to keep the HTML markup out of the query You could use a custom report
template or use the column formatting section within the report attributes to apply some CSS formatting
to the individual column Then the query to bold the names would look like this:
select ename, deptno, sal from emp
Even in this simple example, it’s far easier to see at a glance exactly what this query is doing You can also change the way the data is presented without needing to modify the query definition
Trang 26By keeping the HTML markup out of the query, you may find that your application performs better
if you use the query in multiple places Because the query is already stored in the shared pool, Oracle can take advantage of this by soft-parsing the query If you embed the HTML markup in the query, Oracle will treat two queries as being different, even if only the embedded markup is different For example, this query:
select '<b>' || ename || '</b>' as ename, deptno, sal from emp
would not be considered the same query as this one:
select '<i>' || ename || '</i>' as ename, deptno, sal from emp
If you run the first query and then the second query (for the first time), Oracle won’t find the second query in the shared pool It would need to hard-parse the query, which would be more CPU-intensive than if it had found the query in the shared pool (and therefore could skip the hard-parse)
Whenever you find yourself including HTML in a query, rethink your approach Consider how you
can use SQL features (such as DECODE, NVL, and so on) to add conditional logic to a report template to
distinguish how different columns or rows should be displayed
Using Page Zero
If you want to display the same page element on all or multiple pages of your application, consider making use of page zero When you place a page element on page zero, that element can be seen on all other pages of your application By including some conditional display logic, you can restrict the
element to appear only on certain pages
A common use for page zero is to include a navigational menu in an application You can create a region on page zero that contains the menu, which then appears on every page You can also include a region that contains a navigational menu for administrators You would include a conditional display that shows this menu only if the application user is an administrator
By using page zero, you can centralize common components and functionality within your
application This also leads to a more consistent look and feel, since you can control the layout ofthe elements in a single place
Performance Considerations
You need to consider performance during the design and implementation of a system, rather than investigate it only after you’ve rolled out your application to the live environment (at which point it might be too late to correct any fundamental flaws in the design)
Since the APEX environment runs entirely within the database, many of the recommendations for writing code and good schema design that perform and scale well are the same as for any PL/SQL programs or SQL queries A sound understanding of SQL and PL/SQL is a definite benefit when
developing with APEX Take the time to learn about the latest features available in the database that might enable you to achieve your aims in a different way For example learning how to use analytics might simplify many of your existing queries and make them perform better
Trang 27Bind Variables
The importance of using bind variables in your code can’t be overstated Bind variables not only help
your code perform better, they also help protect you from SQL-injection attacks
For example, say we use the following piece of code to return the SQL that should be used in a
report The code checks whether the user has entered a value for the page item P1_SEARCH If the page
item is not null, the value is appended to the text that is returned
declare
v_sql VARCHAR2(2000);
begin
v_sql := 'select name, salary from payroll where deptno = 10 ';
if p_search is not null then
v_sql := v_sql || 'and name=''' || p_search || '''';
end if;
return v_sql;
end;
So, if the user entered SMITH into the search box, the following SQL would be returned:
select deptno, name, salary from payroll
where deptno = 10 and name = 'SMITH';
However, suppose a malicious user knows you have a function called delete_user with the
following signature:
function delete_user(p_id IN INTEGER) return integer
That user could enter this into the search box:
or delete_user(id) = 1
The query now looks like this:
select id, deptno, name, salary from payroll
where deptno = 10 and name = ' or delete_user(id) = 1'
The seemingly innocent search becomes a mass employee-deletion routine The proper way to
handle this would be to not concatenate the user input directly to the SQL text:
declare
v_sql VARCHAR2(2000);
begin
if :P1_SEARCH is not null then
v_sql := 'select name, salary from payroll where deptno = 10';
else
v_sql := 'select name, salary from payroll '
|| ' where deptno = 10 and name = :P1_SEARCH';
Trang 28Report Pagination Style
Different report pagination styles affect performance when displaying a report For example, some pagination styles will display something like “Row Ranges X to Y of Z,” If you don’t need to display how many total rows are returned from the query, choose a pagination style that displaysonly “Row Ranges X
to Y.” It is worth noting that if you decide to display the total number records the report will return, the database will fetch all the rows, even though you may not display them all If you don’t need to display the total number of rows, the report will be rendered after the rows for the first page are fetched
Error and Exception Handling
Your APEX application can use many different anonymous PL/SQL blocks, functions, procedures, and packages as it executes If an error or exception occurs during the execution of some code, you need to
be able to handle that error or exception gracefully, in such a fashion that flow of execution by the APEX engine is not broken For example, the following code catches an exception and sets the value of an application item:
Trang 29:APP_ERROR_MSG := 'Could not find the employee record.';
end;
You can then display the application item on the page in an HTML region using this syntax:
&APP_ERROR_MSG
You would then create a branch on the page to branch back to itself if the value of the application
item is not null, thereby enabling the user to see the error and correct it
Packaged Code
APEX allows you to write SQL and PL/SQL codedirectly in a number of places via the Application Builder interface For example, suppose you create the following after-submit process in your login page to audit that a user logged in to the application
begin
insert into tbl_audit
(id, user_name, action)
values
(seq_audit.nextval, :APP_USER, 'Logged On');
end;
Now, while this would work, it means that if you ever want to modify the logic of the auditing, you
need to change the application For example, notice that you aren’t currently storing a timestamp of
when the audit action was performed To add that functionality, you’d need to modify the tbl_audit
table and add an extra column to store the timestamp information (if that column didn’t already exist), and then edit the application to change the PL/SQL page process to include the timestamp information, like this:
begin
insert into tbl_audit
(id, ts, user_name, action)
values
(seq_audit.nextval, sysdate, :APP_USER, 'Logged On');
end;
So, for a very simple change, you might need to modify the application in development, export a
new version of the application, import that version into a test environment, and so on through to
Trang 30or to add new columns and reference session state items without needing to change anything in the application itself All you’d need to do is recompile the new package body in the development, test, or production environment This would result in much less downtime for the application, since you no longer need to remove the old version of the application and import the new version This method really does allow downtimes of just a few seconds (the time it takes to recompile the package body), as
opposed to minutes, or potentially hours, while new versions of the applications are migrated If you’re
using the 11gR2 database, you can take advantage of edition-based redefinition, which allows for the
creation of multiple versions of PL/SQL objects Obviously, you won’t always be able to completely encapsulate your logic in packages And sometimes, even if you do encapsulate the logic, you may need
to change something in the application (for example, to pass a new parameter to the packaged code) However, it is good practice to use packaged logic where you can Using packaged code can save you a lot of time later on, as well as encourage you to reuse code rather than potentially duplicating code throughout your application
Another benefit of using packaged code is security The parsing schema can be granted execution privileges on the packaged code only, without having direct grants on the underlying objects This obviates the need for at least two schemas, one to own the objects and another to act as the parsing schema If the parsing schema is compromised, the underlying objects are still protected as only the packaged code is accessible via this schema
Team Development
The Team Development toolset is new in APEX 4.0 These tools enable management of the
development process and tracking of new feature requests, bugs, and milestones Before I delve into how these tools are used, it should be noted that Team Development does not perform source code control That activity, sadly, is still handled as it was in previous versions of APEX and HTMLDB What Team Development does provide is a centralized mechanism for recording requests and tracking the progress of development activities The interface is straightforward but highly configurable, so some planning is required before putting these tools to full use For businesses that use tools like Microsoft Project or Mercury Quality Center to track projects, Team Development may not be necessary But for those without enterprise tools, these new features can be very beneficial—especially because they’re free
Using Team Development
To access the Team Development tools, simply log in to APEX as a developer On the home page, you’ll see the Team Development icon as shown in as shown in Figure 1-22
Trang 31Figure 1-22 Team Development icon
Once inside the Team Development system, you will see the types of project information that can be tracked Figure 1-23 shows the Team Development dashboard Before attempting to use these tools, a
little planning is recommended
Figure 1-23 Team Development dashboard
Preparing for Team Development
To get the maximum benefit from the Team Development tools, it is important to understand the
interrelationships among its five components Features and milestones are the anchor components in a development project Milestones are just what you’d think—a date that has some significance to the
project Once a milestone is defined, it can stand alone or be assigned to features, to dos, and bugs
Features are a little more complex since milestones, bugs, and to dos can be associated with a feature In addition, one feature can be the parent of another This allows for an endless hierarchy of features,
which is why planning is important You don’t want project management to be more complicated than the development process
Trang 32Figure 1-24 shows how you could build a hierarchy of features, bugs, to dos, and milestones withseveral parent-child relationships Figure 1-25 shows a simplified method of managing a project If youequate features to forms or reports, you can see that it’s easier to track features, bugs, to dos, andmilestones using the simplified method
In any case, the Team Development tool offers managers and developers a centralized, web-basedrepository for storing bug reports, user requests, requirement changes, and so forth This is a significantimprovement over the traditional methods for recording this type of information: verbal conversations,handwritten notes, e-mail, etc Since the Team Development interface is web-based, it can be used byanyone, whether APEX is being used for development or not
Figure 1-24 Possible feature hierarchy Figure 1-25 Recommended feature hierarchy
To enable Team Development for a project, the team lead should prepare by identifying the mainfunctions of the application and recording them as features Specific forms and reports are goodcandidates to record as features since users routinely report problems and request changes at theselevels In addition, if any milestones are known, they too can be recorded From that point on, to dosand bugs should be recorded and associated to a feature or a milestone As new features are added, theyshould be recorded as well
A simple workflow for setting up Team Development would include the following:
1 Create features for all known forms, reports, etc
2 Assign any known to dos to their related features
3 Assign dates to any known milestones
As the project progresses, new bugs and to dos can be assigned and the status of completed taskscan be updated
Trang 33Creating Features
To create a feature, click on the Features icon on the Team Development dashboard and then click the
Create button Figure 1-26 shows the Feature entry screen It is important to note that this form allows
you to not only create a feature, but also to populate LOVs, which are used throughout the Team
Development system Fields used to build LOVs are:
• New Owner
• New Contributor
• New Focus Area
• New Release
Because the data entered into these fields is accepted without validation, it can easily become
polluted Please note that the “Release” LOV is populated using this form If Team Development is to be used effectively, data like Release numbers must be tightly controlled For this reason, it is
recommended that access to the Create Feature page be restricted to team leads
Figure 1-26 Create Feature form
The following LOVs are prepopulated at installation and can’t be changed via the Team
Development interface:
• Feature Status
• Desirability
• Priority
Trang 34While many of the fields on this form accept free-form text, Feature Status does not It is used, as you will see later, to aid in project status reporting The remaining attributes of this form are self-explanatory and are common to most project management methodologies
Recording Bugs and To Dos
Once the testing process begins, your users will inevitably begin reporting bugs The Bug form in the Team Development interface is used to record and manage this information The Create Bug form, shown in Figure 1-27, is similar in functionality to the Create Feature form As noted, bugs should be associated with features that equate to a form, report, etc
Figure 1-27 Create Bug page
To dos are similar to bugs in that they are a record of some activity that needs to be done by some date You could consider a to do as anything except a bug Figure 1-28 shows the Create To Do page Determining whether to use the Bug page or the To Do page is up to the team lead As all developers know, testers often report bugs that may actually be requests for new or changed functionality In such cases, the team lead may want to create a To Do so that the development team can address the issues appropriately The main difference between these two objects is that the Bug page can record much more detailed information about the context of the issue
Like the Create Feature page, the Create Bug and To Do pages contain free-form text fields, LOVs, and fields used to populate LOVs Using the recommended project management process, a bug or to do would be created and minimally assigned to a feature and to a developer
Trang 35
Figure 1-28 Create To Do page
It is worth noting that to dos, like features, can be created in a hierarchical fashion Although this is
a powerful feature, it does allow complex hierarchies, which are difficult to track and manage At least in the beginning, it is recommended that the depth of to do (or feature) hierarchies be kept to one or two
levels
Recording a Milestone
A milestone is a significant date within a project plan It can signify the required completion date of
some unit of work, a business critical date like the end of a fiscal year, or something unrelated to the
project like a public holiday The Create Milestone page, shown in Figure 1-29, allows you to create a
milestone, which can then be associated to a Feature, Bug, or To Do
Trang 36Figure 1-29 Create Milestone page
Once a milestone is set, it will show up on its assigned date on the project Calendar as shown in Figure 1-30 The annotation of the milestone (November 12 on the Calendar) is actually a hyperlink that, when clicked, causes the Edit Milestone page to be displayed
Figure 1-30 Project Calendar
Milestones can stand alone or can be assigned to any or all of the project’s features, bugs, or milestones While this can be beneficial in managing a project, it does require the team lead to be diligent in determining how to associate milestones with other objects It is important to note that any feature, bug, or to do can be assigned only one milestone at a time
Trang 37Gathering User Feedback
New in APEX 4.0 is the ability to quickly create a page that lets users report system issues to the
development team lead While this may sound like a handy feature, I may recommend you avoid it for
the following reasons:
• Nontechnical users sometimes have trouble describing system problems in a way
that makes sense to developers
• If you make it very easy to provide feedback, you’ll get lots of it You will then have
to spend time filtering out the “noise” in an effort to determine what is relevant
and what is not
I’ve been writing code and working with users for more than 20 years, and during that time I’ve
followed one simple approach regarding user feedback: without meaning any disrespect, I don’t believe what anyone says about an application bug until I see it myself When you are intimately familiar with a piece of code, no one can describe a bug in that code better than you If at all possible, I recommend
having a lead developer meet with the user community (or their reasonable facsimile) on a regular basis The developer can then translate users’ concerns into actionable items for the development team
If you decide you want to include a Feedback page in your system, here’s is a brief description of
how to do it:
1 Add a page to an application, selecting “Feedback” as the type
2 Select “Yes” to add a Navigation Bar entry
3 Set the label for the Navigation Bar entry
4 Select “Yes” to Enable Feedback for this application
Once you complete this process, your users can access the Feedback page from the Navigation Bar (next to the Login / Logout link) An example is shown in Figure 1-31
Figure 1-31 Feedback page
Trang 38One more time, though, beware of asking for unfiltered end-user feedback You’ll get it
Tracking Development Progress
Without progress reporting, all the time and effort spent recording features, bugs, and to dos would be a waste of time APEX 4.0 addresses this reality by providing mainly dashboards to track project activities The dashboard for each type of work shows progress and status at a glance, but to get more detailed information, additional reports are available The APEX 4.0 Team Development system does not contain
a consolidated report that shows the status of objects across Features, Bugs, and To Dos, but does have a the Team Development home page that contains dashboards for all types of work
The main drawbacks to the Team Development system’s reporting capabilities are:
• Inconsistent status labels across Features, Bugs, and To Dos
• No built-in report that consolidates Features, Bugs, and To Dos
Despite these drawbacks, it is still possible to effectively manage a project using the Team
Figure 1-32 Feature dashboard
Trang 39Bug Dashboard
When you access the Bug dashboard from the Team Development home page, you’ll see a percentage
graphic showing the number of “closed” bugs A closed bug is one that has a status of “100.Complete.”
If you have recorded 2 bugs and closed one, the Bug dashboard will show that 50 percent of the bugs are closed Several additional links on the dashboard, as shown in Figure 1-33, can be used to navigate to
the Bug details page
Figure 1-33 Bug dashboard
To Dos Dashboard
The To Dos dashboard is decidedly different from the Features and Bugs dashboards While this page
does show the completion status of all recorded To Dos as a percentage, it also contains a
doughnut-shaped graphic that shows the percentage of to dos assigned to each developer If you have two
developers and each is assigned one to do, the doughnut will be divided in half to show that each
developer is responsible for 50% of the to dos The graphic also acts as a hyperlink for navigating to a
report of to dos by developer Like bugs, to dos must be 100% complete before the dashboard will show
a completion percentage Figure 1-34 shows the To Do dashboard
Trang 40Figure 1-34 To Do dashboard
Although it may be difficult to see in gray-scale, the doughnut-shaped graphic is divided in half and
is shown in two distinct colors Clicking either half of the graphic or any of the other hyperlinks on this page results in navigation to the associated to do detail page
New Development Features in APEX 4.0
APEX 4.0 includes some interesting new features to assist in development and debugging The APEX Advisor, for instance, is a utility that will scan your application (either completely or by specific page) and report on deviations from “APEX best practices.” You may or may not agree with what the Advisor says, but it makes finding certain type of errors much easier than digging through the code For
example, if you intend to include help on every field on all pages, the Advisor can quickly tell you whether you achieved your goal
APEX Development Advisor
You access the APEX Development Advisor from the Utilities menu of an application home page, as shown in Figure 1-35 You should review each of the Checks to Perform to ensure that you get only the information you need In the Check Pages section, you can include a comma-separated list of page numbers to scan, or leave this area blank to scan all pages