1. Trang chủ
  2. » Công Nghệ Thông Tin

Oracle SQL Plus The Definitive Guide- P13 pps

10 347 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 104 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

In order to get any of the computed values to print, COMPUTE must be used in conjunction with the BREAK command.. In order to print the computed values, you must issue a BREAK command to

Trang 1

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 reportnot something you would normally want to happen

Totals and Subtotals

SQL*Plus allows you to print totals and subtotals in a report To do this, you use a combination of the BREAK

command and one or more COMPUTE commands This section continues where the previous section left off It will show you how to modify the master/detail report created earlier so that it totals the hours and dollars by project and by employee You will also see how to print grand totals for these columns at the end of the report

The COMPUTE Command

The COMPUTE command defines summary calculations needed in a report You can use COMPUTE in conjunction with BREAK to calculate and print column totals, averages, minimum and maximum values, and so on These

calculations are performed by SQL*Plus as the report runs

Syntax of the COMPUTE command

The syntax for the COMPUTE command looks like this:

COMP[UTE] [{AVG¦COU[NT]¦MAX[IUM] ¦ MIN[IMUM] ¦

NUM[BER] ¦ STD ¦ SUM¦VAR [IANCE]} [LABEL label_text]

OF column_name

ON {group_column_name¦ROW¦REPORT} ]

where:

COMP[UTE]

May be abbreviated to COMP Entering COMPUTE with no parameters causes SQL*Plus to list all currently defined computations

Trang 2

AVG

Computes the average of all non-null values for a column AVG only applies to columns of type NUMBER

COU[NT]

Computes the total number of non-null values for a column COUNT may be used with columns of any datatype, and may be abbreviated to COU

MAXI[MUM]

Computes the maximum value returned for a column MAXIMUM may be abbreviated as MAX, and applies to

columns of type NUMBER, CHAR, VARCHAR2, NCHAR, and NVARCHAR2

MINI[UM]

Computes the minimum value returned for a column MINIMUM may be abbreviated as MIN, and applies to columns

of type NUMBER, CHAR, VARCHAR2, NCHAR, and NVARCHAR2

NUM[BER]

Similar to COUNT, but computes the number of all values, including nulls This applies to columns of any datatype, and may be abbreviated to NUM

STD

Computes the standard deviation of all non-null values for a column STD applies only to columns of type NUMBER

SUM

Computes the sum of all non-null values for a column SUM applies only to columns of type NUMBER

VAR[ANCE]

Computes the variance of all non-null values for a column VARIANCE applies only to columns of type NUMBER, and may be abbreviated to VAR

LABEL label_text

Allows you to specify a label for the computed value If possible, this label will be printed to the left of the computed value The label text may be enclosed in quotes, either single or double To embed a quote within the label, when that label has been quoted, place two quote characters back to back

column_name

Is the name of the column you are summarizing If it is a computed column, then the expression is the name If your SELECT statement aliases the column, then you must use that alias here

Trang 3

group_column_name

Causes SQL*Plus to restart the calculation every time this column changes Typically, the report is sorted or grouped by this column, and then the computed value is printed once for each distinct value of the group column

ROW

Causes the computation to be performed once for each row returned by the query

REPORT

Causes the computation to be performed at the end of the report, and to include values from all rows REPORT is used for grand totals

The COMPUTE command is complex, and can be intimidating the first time you go to use it In order to get any of the computed values to print, COMPUTE must be used in conjunction with the BREAK command The next section will show you how this is done

Printing computed values

The COMPUTE command tells SQL*Plus what columns to summarize and over what range of records That's all it does By itself, it won't cause anything to print In order to print the computed values, you must issue a BREAK

command to define breaks on the same report elements used in your COMPUTE command For example, if you total hours by project ID, then you need a project ID break in order to print that total

COMPUTE commands are cumulative

With the BREAK command, you have only one break setting, and each new BREAK command overwrites that setting with a new one That's not the case with COMPUTE Each defined computation is a separate entity, and COMPUTE commands do not overwrite each other COMPUTE definitions also stick for the duration of a SQL*Plus session A COMPUTE setting issued for one report may stick around to affect the printing of subsequent reports SQL*Plus

provides the CLEAR COMPUTES command to help you deal with this CLEAR COMPUTES causes SQL*Plus to erase all computations so you can start over If you are using COMPUTE in a report script, you may want to include a CLEAR COMPUTES command to avoid any possible contamination from previous reports that may have used

COMPUTE

Printing Subtotals

The Project Hours and Dollars Detail report has two numeric columns showing the hours logged to a project together with the resulting dollar amount that was

Trang 4

charged You can easily see that it would be desirable to total these for each project and employee The following five commands will accomplish this:

CLEAR COMPUTES

COMPUTE SUM LABEL Totoals OF hours_logged ON project_id

COMPUTE SUM LABEL Totals OF dollars_charged ON project_id

COMPUTE SUM LABEL Totals OF hours_logged ON employee_id

COMPUTE SUM LABEL Totals OF dollars_charged ON employee_id

The first command simply clears any existing computations that may be defined The next two commands summarize the hours and dollars by project The last two commands do the same thing except that the totals are for the employee, and cover all projects to which an employee has charged hours Here's how the output will look when you run the modified script:

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

******* ************************** - -

Totals 20 $3,380.00

1002 Year 2000 Fixes 01-Feb-1998 7 $1,183.00

01-Apr-1998 1 $169.00

01-Jun-1998 3 $507.00

1005 TCP/IP Implementation 01-Jan-1998 5 $845.00

01-Mar-1998 7 $1,183.00

01-May-1998 1 $169.00

01-Jul-1998 3 $507.00

01-Sep-1998 5 $845.00

01-Nov-1998 7 $1,183.00

******* ************************** - -

Totals 28 $4,732.00

- -

116 $19,604.00

Trang 5

Notice that the label Totals appears in the project_id column SQL*Plus always places the label you specify into the ON column of the COMPUTE command The label will be formatted according to the rules specified in that column's

COLUMN command

Only one label can be printed for project totals, though there are two COMPUTE commands Had you specified two different labels, the first one would have taken precedence

Why no label for the employee totals? Because this is a master/detail report, and the NOPRINT option has been used to suppress printing of the employee_name and employee_id columns Normally, SQL*Plus would print the COMPUTE label in the employee_id column, but that can't be done if the column is not being printed There is really nothing you can do if you aren't happy with this behavior You either have to live with it or avoid master/detail reports

The width of the label identifying the project totals is limited by the width of the project_idcolumn, which simply won't hold a longer, more descriptive label such as Project Totals However, there are a couple of things you can do to make room for a longer label The first and most obvious thing is simply to make the project_column wider Change the COLUMN command to widen the field from 7 to 14 digits:

COLUMN project_id HEADING Proj ID FORMAT 99999999999999

Just be sure to bump up the linesize setting by the same amount, and also adjust the page headers and footers

A less obvious approach would be to change the computations so the project totals are summarized for each project name rather than for each project ID The resulting commands would be:

COMPUTE SUM LABEL Project Totals OF hours_logged ON project_name

COMPUTE SUM LABEL Project Totals OF dollars_charged ON project_name

The output would then look like this:

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

************************** - -

Project Totals 20 $3,380.00

Trang 6

You now have room for a more descriptive label, and there is the added benefit that it looks better with the label

indented closer to the printed totals

Print Grand Totals

The REPORT keyword is used to compute and print totals for an entire report Use REPORT in the ON clause of a COMPUTE statement to define report-level computations Use REPORT with the BREAK command to enable a report break that will cause the report-level computed values to print

To print grand totals for the project_hours and dollars_charged columns, add the following two lines to the script file: COMPUTE SUM LABEL Grand Totals OF hours_logged ON REPORT

COMPUTE SUM LABEL Grand Totals OF dollars_charged ON REPORT

Notice that instead of specifying a column in the ON clause, the keyword REPORT has been used This tells SQL*Plus

to sum the data over the entire report Also notice that the LABEL clause has been used Normally the label would print

in the column specified in the ON clause In cases like this where there is no ON column, SQL*Plus will place the labels in the first column of the report

The next thing to do is to modify the BREAK command by adding a report break Forget to do this and the report totals will not print The final version of the BREAK command looks like this:

BREAK ON REPORT -

ON employee_id SKIP PAGE NODUPLICATES -

ON employee_name NODUPLICATES -

ON project_id SKIP 2 NODUPLICATES -

ON project_name NODUPLICATES

The REPORT break was added to the beginning of the BREAK command because it is the outermost break The

position doesn't really matter because SQL*Plus always makes the report break outermost, but I like to put it first

anyway for the sake of clarity

If you run the report now, the grand totals will be printed on a page by themselves at the end of the report Here's how that output will look:

The Fictional Company

I.S Department Project Hours and Dollars Details

============================================================

Employee: 113 Jacob Marley

Trang 7

Dollars

Proj ID Project Name Date Hours Charged

- - - - -

- -

786 $110,779.00

Notice three things about how the report totals are printed First, notice that they printed on a page by themselves Next, notice that the page with the grand totals still shows an employee name in the page header Finally, notice that the

Grand Totals label did not print as expected in the first column I'll explain all of these oddities next

First the pagination issue Before SQL*Plus executes a report break, it first executes all the other breaks Execution begins with the innermost break and proceeds outwards until the report break actions are executed In this example, SQL*Plus will skip two linesthe project break and the skip to a new pagethe employee break, and then print the report totals This is usually the behavior you want when printing a master/detail report You may intend to give each

employee his own section of the report so he can double-check his hours Since the grand total doesn't really belong with any one employee, you don't want it on the pages you are giving out

The last employee's name printed on the page header simply because it was the last value retrieved from the database It would be nice if SQL*Plus were smart enough to make this value null or blank, but it isn't The value in the header is refreshed only when a new value is read from the database, and in the case of a report break, that simply doesn't happen This is only an issue on master/detail reports when you use variables to include report data in the header

The final item to notice, and the only one you can do anything about, is the lack of a label for the grand total values I did say that SQL*Plus puts the label for report-level calculations in the first column of the report Contrary to what you might intuitively expect, SQL*Plus bases the first column on the SELECT statement, not on what is actually printed When this report was converted to a master/ detail report, printing of the first two columns was suppressed using the NOPRINT clause of the COLUMN command No employee_id column, no Grand Totals label

Since the employee_id and employee_name columns are not being printed, their position in the SELECT statement is irrelevant You can move them to the end, making project_id the first column, widen the project_id column to hold 12 characters instead of 7, and the Grand Totals label will now print in the first column of the report

The final listing, complete with the changes that allow the Grand Totals label to print, is shown next To widen the project_id column to accommodate 12

Trang 8

characters, 5 extra leading spaces were inserted into the project_id column title The linesize was also adjusted from 66 to 71, and 5 equal-sign characters were added to the ruling lines in the header and footer

Setup pagesize paremeters

Set NEWPAGE 0

SET PAGESIZE 35

Set the linesize, which must match the number of equal signs used

for the ruling lines in the headers and footers

SET LINESIZE 71

Setup 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: lsquo; 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 REPORT -

ON employee_id SKIP PAGE NODUPLICATES -

ON employee_name NODUPLICATES -

ON project_id SKIP 2 NODUPLICATES -

ON project_name NODUPLICATES -

CLEAR COMPUTES

COMPUTE SUM LABEL Project Totals OF hours_logged ON project_name

COMPUTE SUM LABEL Project Totals OF dollars_charged ON project_name

COMPUTE SUM LABEL Totals OF hours_logged ON employee_id

COMPUTE SUM LABEL Grand Totals OF dollars_charged ON REPORT

COMPUTE SUM LABEL Grand Totals OF hours_charged ON REPORT

COMPUTE SUM LABEL Grand Totals OF dollars_charged ON REPORT

Execute the query to generate the report

SELECT P.PROJECT_ID,

P.PROJECT_NAME,

TO_CHAR(PH.TIME_LOG_DATE, dd-Mon-yyyy) time_log_date,

PH.HOURS_LOGGED,

PH.DOLLARS_CHARGED,

E.EMPLOYEE_ID,

E.EMPLOYEE_NAME

Trang 9

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;

Here is the output produced by the final version of this script Notice that the Grand Totals label does appear in the

project_id column at the end of the report

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

************************** - -

Project Totals 20 3,380.00

detail for several projects

1005 TCP/IP Implementation 01-Jan-1998 5 $845.00

01-Mar-1998 7 $1,183.00

01-May-1998 1 $169.00

01-Jul-1998 3 $507.00

01-Sep-1998 5 $845.00

01-Nov-1998 7 $1,183.00

************************** - -

Project Totals 28 $4,732.00

************ - -

116 $19,604.00

severalpages of output

The Fictional Company

I.S Department Project Hours and Dollars Detail

======================================================================

Trang 10

Employee: 113 Jacob Marley

Dollars

Proj ID Project Name Date Hours Charged

- - - - -

- -

Grand Totals 786 $110,779.00

When printing totals and grand totals, be sure that the summarized columns are wide enough to accommodate the final totals None of the individual Dollars Charged values in this report required more than four digits to the left of the decimal, but the final total required six

Other Reporting Topics

In addition to what you've read so far in this chapter, there are several other techniques and topics worth discussing One

is a method for getting the current date into your page titles Considering how easy it is to do page numbers, it's

surprisingly difficult to do dates Report headers and footers function similarly to page headers and footers, except that they print just once, at the beginning and end of a report

If you find yourself printing reports only because you need to look at computed values such as group totals and report totals, you will want to read the section on summary reports that follows You can save yourself a lot of network and other overhead by summarizing your data on the server instead of returning all the detail records and making SQL*Plus

do the work

Getting the Current Date into a Header

It's a very common practice to put the run date in the header of a report It's such a common practice, in fact, that it's a wonder Oracle does not provide a convenient way to do it Unlike the case with the page number, which SQL*Plus conveniently maintains in the SQL.PNO user variable, the date is not so easily available How then, do you display the date in the page header? The answer is to retrieve it from the database, put it into a user variable, and display that

variable in the header

You saw how to display the contents of a user variable in the header when the Project Hours and Dollars Detail report was converted to a master/detail style You also saw how to use the COLUMN command to tell SQL*Plus to

continuously update the contents of a user variable with the value of a column in the query Getting the system date to display in the header involves a little trick that takes advantage of this use of the COLUMN command The trick is to execute a query

Ngày đăng: 05/07/2014, 04:20

TỪ KHÓA LIÊN QUAN