Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Raj.

Asked: October 12, 2004 - 4:46 pm UTC

Last updated: October 13, 2004 - 12:12 pm UTC

Version: 9.2.0

Viewed 1000+ times

You Asked

Hi Tom, I would like your advise/opinion on a reporting issue. We have a reporting requirement whereby the user would schedule a report for execution and few hours or a day later come back and view the report output. Some developers are asking me to store the report output in the database, in the form of a table (a separate db table for every report run!!) so that it would be easier for them to display results when the user choses to view the report. I am vehemently denying this. A new table in the db for every report!! Ofcourse I can run a nightly job to drop tables that are 'x' days old but I don't feel comfortable with the application creating/dropping tables.
1. My thinking is that processed data (such as reports) doesn't belong in the db, only raw data does. What do you think?
2. Also the report logic (a java stored procedure) would insert the report rows one at a time in this report table. I am saying that will generate a lot of redo - store the report rows in a csv file on the disk, instead. But they claim that it will be difficult for them to paginate thru the rows (first 20 rows, next , previous) from a file - they can easily do this when selecting from a db table.

Can you please provide your views and arguments?

Thanks.


and Tom said...

i disagree -- data is data. data belongs in the database.

However, a table per report -- that would be "not so smart"

Seems to me a single table would be able to support anything. What are they generating the reports in? are they producing HTML? PDF? XLS? what? what is the OUTPUT format of these reports.


If the data is simply "rows and columns", a single table would suffice for all users:


create table report_lines
( report_id int, seq int,
vc_column1 varchar2(4000),
vc_column2 varchar2(4000),
...
vc_column500 varchar2(4000),
num_column1 number,
num_column2 number,
.....
num_column500 number,
ts_column1 timestamp,
ts_column2 timestamp,
....
ts_column500 timestamp,
primary key(report_id,seq) );


And then they just:

insert into report_header (report_id, time_of_report, username, <whatever>)
values ....;

insert into report_lines (report_id,seq, <whatever columns they need>)
select report_id_seq.currval, rownum, <whatever columns they need>
from (THEIR_QUERY_INCLUDING_ORDER_BYS);


and there you go. You would periodically truncate or dbms_redef this table *if needed* but queries of the form

select <columns>
from report_lines
where report_id = :x
and seq between :lo and :hi;

would always return very fast using the primary key to get the 10/20 rows needed.

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Single table/dbms_redef sounds good - Further input

Raj, October 13, 2004 - 11:16 am UTC

Thanks for your answer, Tom. The final report is HTML but as I understand there is already some sort of framework in place to read rows/columns of data and render them on the browser in HTML. So yes, for this discussion, it is rows/columns of data. I like your idea of one report_lines table.

The only thing is the report logic is kind of complicated and would not always be achievable in a single 'insert into report_lines select ...' statement, rather:

-declare a cursor that would fetch say 5000 rows
-for each row, do calc./logic and come up with finished row
-insert "finished" row into report_lines
- process next row.

So there will be 5000 individual inserts in report_lines table. If this happens for every report, should I be concerned about the amount of redo generated? As I underdtand from your various replies, nologging works only in some specific cases so I take it that creating report_lines table nologging or in a separate nologging tablespace wouldn't help reduce redo log, correct?

I also like your idea of dbms_redef (if truncate is not possible).

Thanks in advance.

Tom Kyte
October 13, 2004 - 12:12 pm UTC

tell them to use insert batching (a simple "setter" function call on the prepared statement they'll be using).

Oracle will save up N records in the client before sending them over.

it'll bulk it right up.

(they should write this report generator in plsql -- it would take less time to code and be overall better since they are just

a) fetching data
b) working with data
c) inserting data.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library