The Break Command The BREAK command is used to define page breaks and line breaks based on changing column values in a report.. Suppressing Duplicate Column Values To eliminate repeating
Trang 1LEFT ======================================== -
================================= -
SKIP 2
BTITLE LEFT ======================================== -
================================= -
SKIP 1 -
RIGHT Page FROMAT 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 porject_name HEADING Project Name FORMAT A12 WORD_WRAPPED
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 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
101 Jonathan Gennick 1001 Corporate Web 01-Mar -1998 3 $507.00
Site
101 Jonathan Gennic 1001 Corporate Web 01-May-1998 5 $845.00
Site
101 Jonathan Gennick 1001 Corporate Web 01-Jul-1998 7 $1,183.00 Site
Trang 2
101 Jonathan Gennick 1001 Corporate Web 01-Sep-1998 1 $169.00 Site
101 Jonathan Gennick 1001 Corporate Web
01-Nov-1998 0 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 2002 Fixes
01-Oct-1998 7 $1,183.00
101 Jonathan Gennick 1002 Year 2002 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 {columns_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
Trang 3
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
Trang 4
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.
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
Trang 5
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
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:
This Fictional Company
I.S.Department Project Hours and Dollars Detail
====================================================================================
Dollars
Emp ID Employee Name Proj ID Project Name Date Hours Charged
- - - - - - -
- -
101 Jonathan Gennic 1001 Corporate Web 01-Jan-1998 1 $169.00
Site
Trang 6
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 Ficional 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.
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 -
Trang 7
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 footerjust what we are
going to do here Chapter 4, Writing SQL*Plus Scripts, 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
Trang 8
ple, 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 linethe 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 SQLlus to print the contents of this user variable, which contains the most recently retrieved employee name.
Trang 9
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
Trang 10
1002 Year 20000 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 paremeters
SET NEWPAGE 0
SET PAGESIZE 55
Set the linesize, which must be 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
TITLE 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 FROMAT 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 Computaions
BREAK ON employee_id SKIP PAGE NODUPLICATES -
ON employee_name NODUPLICATES -
ON employee_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