Advanced Report Formatting

You can add page breaks and line breaks to your reports with the BREAK command. BREAK is also commonly used to suppress repeating values in report columns. Take a look at the following script, which generates a detailed listing of all time charged to each project by each employee:

—Set up pagesize parameters
SET NEWPAGE 0
SET PAGESIZE 55

—Set the linesize, which must match the number of equals signs used
—for the ruling lines in the headers and footers.
SET LINESIZE 77

—Set up page headings and footings
TTITLE CENTER 'The Fictional Company' SKIP 3 -
       LEFT 'I.S. Department' -
       RIGHT 'Project Hours and Dollars Detail' SKIP 1 -
       LEFT '========================================' -
            '====================================' -
       SKIP 2

BTITLE LEFT '========================================' -
            '====================================' -
       SKIP 1 -
       RIGHT 'Page ' FORMAT 999 SQL.PNO

—Format the columns
COLUMN employee_id HEADING 'Emp ID' FORMAT 9999
COLUMN employee_name HEADING 'Employee Name' FORMAT A16 WORD_WRAPPED
COLUMN project_id HEADING 'Proj ID' FORMAT 9999
COLUMN project_name HEADING 'Project Name' FORMAT A12 WORD_WRAPPED
COLUMN time_log_date HEADING 'Date' FORMAT A11
COLUMN hours_logged HEADING 'Hours' FORMAT 9,999
COLUMN dollars_charged HEADING 'Dollars|Charged' FORMAT $999,999.99

—Execute the query to generate the report.
SELECT E.EMPLOYEE_ID,
       E.EMPLOYEE_NAME,
       P.PROJECT_ID,
       P.PROJECT_NAME,
       TO_CHAR(PH.TIME_LOG_DATE,'dd-Mon-yyyy') time_log_date,
       PH.HOURS_LOGGED,
       PH.DOLLARS_CHARGED
  FROM EMPLOYEE E,
       PROJECT P,
       PROJECT_HOURS PH
 WHERE E.EMPLOYEE_ID = PH.EMPLOYEE_ID
   AND P.PROJECT_ID = PH.PROJECT_ID
ORDER BY E.EMPLOYEE_ID, P.PROJECT_ID, PH.TIME_LOG_DATE;

When you execute this script, here’s what the output will look like:

The Fictional Company


I.S. Department                              Project Hours and Dollars Detail
=============================================================================

                                                                                 
                                                                      Dollars
Emp ID Employee Name    Proj ID Project Name     Date         Hours   Charged
------ ---------------- ------- ---------------- ----------- ------ ---------
   101 Jonathan Gennick    1001 Corporate Web    01-Jan-1998      1   $169.00
                                Site

   101 Jonathan Gennick    1001 Corporate Web    01-Mar-1998      3   $507.00
                                Site

   101 Jonathan Gennick    1001 Corporate Web    01-May-1998      5   $845.00
                                Site

   101 Jonathan Gennick    1001 Corporate Web    01-Jul-1998      7 $1,183.00
                                Site

   101 Jonathan Gennick    1001 Corporate Web    01-Sep-1998      1   $169.00
                                Site

   101 Jonathan Gennick    1001 Corporate Web    01-Nov-1998      3   $507.00
                                Site

   101 Jonathan Gennick    1002 Year 2000 Fixes  01-Feb-1998      7 $1,183.00
   101 Jonathan Gennick    1002 Year 2000 Fixes  01-Apr-1998      1   $169.00
   101 Jonathan Gennick    1002 Year 2000 Fixes  01-Jun-1998      3   $507.00
   101 Jonathan Gennick    1002 Year 2000 Fixes  01-Aug-1998      5   $845.00
   101 Jonathan Gennick    1002 Year 2000 Fixes  01-Oct-1998      7 $1,183.00
   101 Jonathan Gennick    1002 Year 2000 Fixes  01-Dec-1998      1   $169.00

The first four columns repeat the same values over and over again. This makes the report a bit difficult to follow because you may not see when a value actually changes. Next, you will see how to suppress duplicate values in a column, making the report less repetitious. You will also see how to add page and line breaks to further improve readability. Finally, you will learn how to turn this report into a master/detail report that shows the employee information in the page header with the detail listed below it.

The BREAK Command

The BREAK command is used to define page breaks and line breaks based on changing column values in a report. It controls whether or not duplicate values print in a column, and it controls the printing of computed values such as totals and subtotals.

The BREAK command looks like this:

BRE[AK] [ON {column_name|ROW|REPORT}
        [SKI[P] {lines_to_skip|PAGE}|
        NODUP[LICATES]|
        DUP[LICATES]...]

where:

BRE[AK]

May be abbreviated BRE. Issuing the BREAK command with no parameters causes SQL*Plus to display the current break setting.

column_name

Specifies a report column to watch. When the value in the column changes, SQL*Plus skips lines or pages as specified. SQL*Plus also inhibits repeating, or duplicate, values from printing more than once unless the DUPLICATES keyword is used.

ROW

Causes SQL*Plus to break on each row. You could double-space a report by using BREAK ON ROW SKIP 1.

REPORT

Specifies a report-level break, and is used to cause SQL*Plus to print grand totals at the end of the report. SKIP PAGE will be ignored if it is specified as a report break action, but strangely enough, the other form of the SKIP parameter will work. You can skip lines on a report break.

SKI[P] lines_to_skip

Tells SQL*Plus to skip the specified number of lines when a break occurs. SKIP may be abbreviated to SKI.

SKI[P] PAGE

Tells SQL*Plus to advance to a new page when a break occurs.

NODUP[LICATES]

Tells SQL*Plus to print a column’s value only when it changes. By default, whenever you put a break on a column, you get this behavior. May be abbreviated NODUP.

DUP[LICATES]

Forces SQL*Plus to print a column’s value in every line on the report, regardless of whether or not the value is the same as that printed for the previous record. May be abbreviated as DUP.

SQL*Plus only allows one break setting to be in effect at any given time, but any number of ON clauses may be used in order to accommodate breaks on more than one column. Longer BREAK commands that define breaks on many columns end up looking like this:

BREAK ON column_name 
               action ON column_name 
               action -
        ON column_name 
               action ON column_name 
               action...

The hyphen on the end of the first line is the SQL*Plus continuation character, and allows you to improve readability by splitting long commands across several physical lines.

You should almost always sort or group your report by the same columns specified in the BREAK command, and the column orders should match.

Suppressing Duplicate Column Values

To eliminate repeating values in a report column, use the BREAK command to specify the NODUPLICATES action for that column. For example, to eliminate duplicate values in the employee and project name columns, as well as the employee and project ID columns, you could issue this command:

BREAK ON employee_id NODUPLICATES ON employee_name NODUPLICATES
      ON project_id NODUPLICATES ON project_name NODUPLICATES

NODUPLICATES is the default action for BREAK and is almost never specified explicitly. Instead, the command just shown would usually be simplified to:

BREAK ON employee_id ON employee_name ON project_id ON project_name

Adding this BREAK command to the report script makes the output look like this:

The Fictional Company


I.S. Department                              Project Hours and Dollars Detail
=============================================================================

                                                                         
                                                                      Dollars
Emp ID Employee Name    Proj ID Project Name     Date         Hours   Charged
------ ---------------- ------- ---------------- ----------- ------ ---------
   101 Jonathan Gennick    1001 Corporate Web    01-Jan-1998      1   $169.00
                                Site

                                                 01-Mar-1998      3   $507.00
                                                 01-May-1998      5   $845.00
                                                 01-Jul-1998      7 $1,183.00
                                                 01-Sep-1998      1   $169.00
                                                 01-Nov-1998      3   $507.00
                           1002 Year 2000 Fixes  01-Feb-1998      7 $1,183.00
                                                 01-Apr-1998      1   $169.00
                                                 01-Jun-1998      3   $507.00
                                                 01-Aug-1998      5   $845.00
                                                 01-Oct-1998      7 $1,183.00
                                                 01-Dec-1998      1   $169.00

As you can see, this is a vast improvement over the previous version of the report. You can now easily spot changes in the employee and project columns.

Tip

When using the BREAK command, your query should use an appropriate ORDER BY or GROUP BY clause to group related records together. It wouldn’t make much sense to break on the employee_name column if all records for one employee weren’t grouped together. The query for this example sorts by employee_id and project_id. Because there is a one-to-one correlation between employee_id and employee_name, there is no need to specify both in the ORDER BY clause. The same holds true for project_id and project_name.

Page and Line Breaks

To further aid readability, you might wish to start a new page when the employee name changes, and to leave one or two blank lines between the detail for each project. Having each employee start on a new page has the further benefit of allowing you to give each employee his section of the report. Perhaps you want him to double-check the hours he has reported. The SKIP action of the BREAK command can be used to accomplish both these objectives.

Adding a page break

To have each employee’s data start on a new page, add SKIP PAGE to the list of actions to be performed each time the employee changes. The resulting BREAK command looks like this:

BREAK ON employee_id SKIP PAGE NODUPLICATES -
      ON employee_name NODUPLICATES -
      ON project_id NODUPLICATES -
      ON project_name NODUPLICATES

Tip

Since both the employee ID and name columns change at the same time, the page break could have been defined on either column. In this case, the employee_id was chosen because it is the primary key for the table and can be depended on to be unique for each employee.

Adding a line break

To add two blank lines between projects, use the SKIP 2 action. SKIP allows you to advance a specified number of lines each time a column’s value changes. It takes one numeric argument specifying the number of lines to advance. Here’s how the BREAK command looks with both the page and line breaks specified:

BREAK ON employee_id SKIP PAGE NODUPLICATES -
      ON employee_name NODUPLICATES -
      ON project_id SKIP 2 NODUPLICATES -
      ON project_name NODUPLICATES

Report output with page and line breaks

When you run the report using this BREAK setting, the output will look like this:

The Fictional Company


I.S. Department                              Project Hours and Dollars Detail
=============================================================================

                                                                         
                                                                      Dollars
Emp ID Employee Name    Proj ID Project Name     Date         Hours   Charged
------ ---------------- ------- ---------------- ----------- ------ ---------
   101 Jonathan Gennick    1001 Corporate Web    01-Jan-1998      1   $169.00
                                Site

                                                 01-Mar-1998      3   $507.00
                                                 01-May-1998      5   $845.00
                                                 01-Jul-1998      7 $1,183.00
                                                 01-Sep-1998      1   $169.00
                                                 01-Nov-1998      3   $507.00


                           1002 Year 2000 Fixes  01-Feb-1998      7 $1,183.00
                                                 01-Apr-1998      1   $169.00
                                                 01-Jun-1998      3   $507.00
                                                 01-Aug-1998      5   $845.00
                                                 01-Oct-1998      7 $1,183.00
                                                 01-Dec-1998      1   $169.00
...
                             The Fictional Company


I.S. Department                              Project Hours and Dollars Detail
=============================================================================

                                                                      Dollars
Emp ID Employee Name    Proj ID Project Name     Date         Hours   Charged
------ ---------------- ------- ---------------- ----------- ------ ---------
   102 Jenny Gennick       1001 Corporate Web    01-Jan-1998      1   $135.00
                                Site

                                                 01-Mar-1998      3   $405.00
                                                 01-May-1998      5   $675.00

As you can see, each change in employee starts a new page, and there are now two blank lines following each project.

Tip

Sometimes column breaks and page breaks coincide. When that happens, SQL*Plus will perform both sets of break actions, which can result in some pages that start with leading blank lines. In this example, if both a project and a page break occur simultaneously, SQL*Plus will first advance to a new page, then print the two blank lines required for a project break. SQL*Plus has not been designed to recognize that, because of the page break, the two blank lines are not needed.

When using BREAK to create page breaks and lines breaks, it is important that the column order specified in your BREAK command match the sort order (or grouping) used for the query. This is very important! Suppose you took the BREAK command just used and turned it around like this:

BREAK ON project_id SKIP 2 NODUPLICATES -
      ON project_name NODUPLICATES -
      ON employee_id SKIP PAGE NODUPLICATES -
      ON employee_name NODUPLICATES

You would find that every change in project resulted in a skip to a new page. Why? Because when SQL*Plus executes a break action for a given column, it first executes the break actions for all columns to the right of it in the list. The reason it does that is because column breaks are also used to trigger the printing of totals and subtotals. If you were totaling up hours by project and employee, and the employee changed, it would be important to print the total hours for the employee’s last project prior to printing the total hours for that employee.

Master/Detail Formatting

With column breaks on both the employee columns and the project columns, the Project Hours and Dollars Detail report now contains quite a bit of whitespace. This is particularly true under the employee name column because that value changes so infrequently. This report is a good candidate for conversion to a master/detail style of report.

A master/detail report is one that displays the value of one record in a heading and then lists the detail from related records below that heading. The record shown in the heading is referred to as the master, and the records shown below that heading are referred to as detail records.

Only three additional steps are needed to convert this report from a plain columnar report to the master/detail style of report:

  1. Retrieve the employee name and ID into user variables.

  2. Modify the page heading to print the value of those variables.

  3. Revise the report width and the width of the remaining fields.

User variables are text variables that can be used to hold values retrieved from the database or to hold values entered by a user. One use for user variables is to allow you to include report data as part of a page header or footer — just what we are going to do here. Chapter 4, talks about using these variables to facilitate user interaction with your SQL*Plus scripts.

Retrieve the employee information into user variables

Use the COLUMN command to get the value of the employee name and ID columns into user variables. Instead of specifying a display format for those columns, use the NEW_VALUE and NOPRINT clauses. For example:

COLUMN employee_id NEW_VALUE emp_id_var NOPRINT
COLUMN employee_name NEW_VALUE emp_name_var NOPRINT

The NEW_VALUE clause tells SQL*Plus to update a user variable with the new contents of the column each time a row is returned from the query. In this example, emp_name_var will be updated by SQL*Plus to contain the most recently retrieved employee name. Likewise, the emp_name_id variable will be updated with the employee ID. It is not necessary to declare these variables. Simply pick some names that make sense and use them. The NOPRINT clause is used to tell SQL*Plus not to include the employee name and ID columns in the report detail.

Modify the page heading to print the employee name and ID

The next step is to modify the page header to include the employee information. That can be done using this updated TTITLE command:

TTITLE CENTER 'The Fictional Company' SKIP 3 -
       LEFT 'I.S. Department' -
       RIGHT 'Project Hours and Dollars Detail' SKIP 1 -
       LEFT `=============================================================' -
       SKIP 2 'Employee: ' FORMAT 9999 emp_id_var ' ' emp_name_var SKIP 3

The only change to the header is the addition of a fifth line — the bold line in the example. Here’s how to interpret this line:

SKIP 2

Tells SQL*Plus to advance two lines after printing the ruling line of equal-sign characters. This effectively leaves one blank line before the employee ID and name are printed.

`Employee: '

This is a quoted literal, so SQL*Plus prints it just as it is shown. It serves to label the information that follows.

FORMAT 9999

Tells SQL*Plus to format any subsequent numeric values in a four-digit field with no leading zeros.

emp_id_var

Tells SQL*Plus to print the contents of this user variable, which contains the most recently retrieved employee ID number.

` '

Causes a space to print between the employee ID and name so the two fields don’t run together.

emp_name_var

Tells SQL*Plus to print the contents of this user variable, which contains the most recently retrieved employee name.

Tip

It’s usually not necessary to format a character field such as the employee name, but you do have that option. Specifying FORMAT A20 TRUNCATED, for example, will cause the employee name to print in a 20-character-wide field with any names longer than 20 characters being truncated.

Revisit the report width and the width of the remaining fields

The employee_name and employee_id columns used a total of 22 characters. Since each column was followed by one blank space, eliminating them from the detail section of the report frees up 24 characters that may be usable elsewhere.

The one column that can benefit from a longer length is the project_name column. This column prints 12 characters wide on the report, but is defined in the database to hold up to 40. A quick look at the actual data shows that all but one project name is 26 characters or less, so let’s increase it to 26 by changing its COLUMN command to:

COLUMN project_name HEADING 'Project Name' FORMAT A26 WORD_WRAPPED

The remaining 10 characters can be taken out of the linesize, which is currently 76, so the new linesize command becomes:

SET LINESIZE 66

By adjusting the linesize, you ensure that the right-justified portions of the page title line up with the right edge of the report. Remember to adjust the number of equal-signs in the TTITLE and BTITLE commands to match the linesize. The report output will now look like this:

The Fictional Company


I.S. Department                   Project Hours and Dollars Detail
==================================================================

Employee:   101 Jonathan Gennick


                                                           Dollars
Proj ID Project Name               Date         Hours      Charged
------- -------------------------- ----------- ------ ------------
   1001 Corporate Web Site         01-Jan-1998      1      $169.00
                                   01-Mar-1998      3      $507.00
                                   01-May-1998      5      $845.00
                                   01-Jul-1998      7    $1,183.00
                                   01-Sep-1998      1      $169.00
                                   01-Nov-1998      3      $507.00


   1002 Year 2000 Fixes            01-Feb-1998      7    $1,183.00
                                   01-Apr-1998      1      $169.00
                                   01-Jun-1998      3      $507.00
                                   01-Aug-1998      5      $845.00
                                   01-Oct-1998      7    $1,183.00
                                   01-Dec-1998      1      $169.00

Here is the final version of the script, incorporating all the changes described in this section:

--Set up pagesize parameters
SET NEWPAGE 0
SET PAGESIZE 55
--Set the linesize, which must match the number of equals signs used
--for the ruling lines in the headers and footers.
SET LINESIZE 66

--Set up page headings and footings
TTITLE CENTER 'The Fictional Company' SKIP 3 -
       LEFT 'I.S. Department' -
       RIGHT 'Project Hours and Dollars Detail' SKIP 1 -
       LEFT '========================================' -
            '==========================' -
       SKIP 2 'Employee: ' FORMAT 9999 emp_id_var ' ' emp_name_var SKIP 3

BTITLE LEFT '========================================' -
            '==========================' -
       SKIP 1 -
       RIGHT 'Page ' FORMAT 999 SQL.PNO

--Format the columns
COLUMN employee_id NEW_VALUE emp_id_var NOPRINT
COLUMN employee_name NEW_VALUE emp_name_var NOPRINT
COLUMN project_id HEADING 'Proj ID' FORMAT 9999
COLUMN project_name HEADING 'Project Name' FORMAT A26 WORD_WRAPPED
COLUMN time_log_date HEADING 'Date' FORMAT A11
COLUMN hours_logged HEADING 'Hours' FORMAT 9,999
COLUMN dollars_charged HEADING 'Dollars|Charged' FORMAT $999,999.99

--Breaks and Computations
BREAK ON employee_id SKIP PAGE NODUPLICATES -
      ON employee_name NODUPLICATES -
      ON project_id SKIP 2 NODUPLICATES -
      ON project_name NODUPLICATES

--Execute the query to generate the report.
SELECT E.EMPLOYEE_ID,
       E.EMPLOYEE_NAME,
       P.PROJECT_ID,
       P.PROJECT_NAME,
       TO_CHAR(PH.TIME_LOG_DATE,'dd-Mon-yyyy') time_log_date,
       PH.HOURS_LOGGED,
       PH.DOLLARS_CHARGED
  FROM EMPLOYEE E,
       PROJECT P,
       PROJECT_HOURS PH
 WHERE E.EMPLOYEE_ID = PH.EMPLOYEE_ID
   AND P.PROJECT_ID = PH.PROJECT_ID
ORDER BY E.EMPLOYEE_ID, P.PROJECT_ID, PH.TIME_LOG_DATE;

Printing data in a page footer

You can print data as part of the page footer using the same method just shown for the page header. The only difference is that you would normally use the OLD_VALUE clause with the COLUMN command rather than NEW_VALUE. That’s because when SQL*Plus prints the footer, it has already read the next detail record from the database. Using NEW_VALUE for data in the footer would cause the footer to display information pertaining to the next page in the report — not something you would normally want to happen.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.201.55