SQL> GET test.sql
1 DECLARE
2 TYPE NumTab IS TABLE OF NUMBER(4) INDEX BY BINARY_INTEGER;
3 TYPE NameTab IS TABLE OF CHAR(15) INDEX BY BINARY_INTEGER;
4 pnums NumTab;
5 pnames NameTab;
6 t1 NUMBER(5);
7 t2 NUMBER(5);
8 t3 NUMBER(5);
9
10
11 BEGIN
12 FOR j IN 1..5000 LOOP -- load index-by tables
13 pnums(j) := j;
14 pnames(j) := 'Part No. ' || TO_CHAR(j);
15 END LOOP;
16 t1 := dbms_utility.get_time;
17 FOR i IN 1..5000 LOOP -- use FOR loop
18 INSERT INTO parts VALUES (pnums(i), pnames(i));
19 END LOOP;
20 t2 := dbms_utility.get_time;
21 FORALL i IN 1..5000 -- use FORALL statement
22 INSERT INTO parts VALUES (pnums(i), pnames(i));
23 get_time(t3);
24 dbms_output.put_line('Execution Time (secs)');
25 dbms_output.put_line('---------------------');
26 dbms_output.put_line('FOR loop: ' || TO_CHAR(t2 - t1));
27 dbms_output.put_line('FORALL: ' || TO_CHAR(t3 - t2));
28* END;
SQL> /
Execution Time (secs)
---------------------
FOR loop: 32
FORALL: 3
PL/SQL procedure successfully completed.
Source:
http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96624/05_colls.htm#28087
Take a good look at lines 16 and 20. Then look at line 23.
Ok you lurkers from Oracle ... here's your chance to do a public service
... find whoever managed to do this
and explain to them the concept of why documentation is posted.
Obviously the concept was completely lost
on several people.
Thanks.
--
Daniel Morgan
http://www.outreach.washington.edu/extinfo/certprog/oad/oad_crs.asp
damo...@x.washington.edu
(replace 'x' with a 'u' to reply)
In fairness to Oracle documentation department (for doing a very
boring job), get_time could be a stand alone procedure returning a
call to dbms_utility.get_time, specially if they did a copy/paste job
from a sql buffer after test or else they would have caught the error.
Although I doubt that's the case otherwise they would done the same in
line 16 and 20. It just looks like a typo. -:)
Regards
/Rauf Sarwar
Had they not gotten it correctly twice in the same block I'd be more forgiving. But this? Obviously no one
ever tried this example before including it in the docs.
> Had they not gotten it correctly twice in the same block I'd be more forgiving. But this? Obviously no one
> ever tried this example before including it in the docs.
> --
Or may be the person who create this sample has
done something like this:
create or replace procedure get_time(t out number)
as
begin
t:=dbms_utility.get_time;
end;
/
In his/her own schema. That would, for instance, make the procedure right.
If the person who has created the example is an experienced PL/SQL
programmer, it is very likely that she or he has certain helper procedures
in her or his own schema. Anyway, the procedure illustrates FORALL and
FOREACH clauses very well. I don't find that to be a big deal. On the
other hand, on the oracle mailing list the debate about Oracle Untested
Infuriator (OUI) is just subsiding.
--
Mladen Gogala
Software is like sex, it is better when it is free.
Linus Torvalds
>
> Ok you lurkers from Oracle ... here's your chance to do a public service
> ... find whoever managed to do this
> and explain to them the concept of why documentation is posted.
> Obviously the concept was completely lost
> on several people.
>
FYI (in case you missed it). Every doc has a feedback link -
http://download-west.oracle.com/docs/cd/B10501_01/dcommon/html/feedback.htm
I know the doc writers do read and act on feedback.
Thanks Mark.
Primary Author: John Russell
Contributing Author: Tom Portfolio
Contributors: Shashaanka Agrawal, Cailein Barclay, Dmitri Bronnikov, Sharon
Castledine, Thomas Chang, Ravindra Dani, Chandrasekharan Iyer, Susan
Kotsovolos, Neil Le, Warren Li, Chris Racicot, Murali Vemulapati, Guhan
Viswanathan, Minghui Yang
"Daniel Morgan" <damo...@exxesolutions.com> wrote in message
news:3ED26387...@exxesolutions.com...
Thanks. As a group they should all hang their heads in shame and be forced to
repaint the bottom of one of Larry's boats. ;-)
Thanks to Mark Townsend this has been reported to the proper person(s) and I
expect will be corrected as they seem to do a good job at cleaning things up
when errors are pointed out.
The feedback link isn't exactly obvious :( but I do have a good news story.
Consider
http://download-west.oracle.com/docs/cd/B10501_01/win.920/a95491/specs.htm#1006174
which says if I have a 2k block size I can have no more than 121 extents *in
my database*., not my segment, nor my datafile, nor my tablespace but my
*database* This far outweighs a typo IMO. So I logged a TAR and (after a bit
of ' "this is how unlimited extents works" "no, my point is the limits given
are just daft and meaningless" ') a phone conversation with the docs guys a
doc bug was logged. Net result 'fixed in next release' - and yes I will
check. I made a point of going through the iTar route and it works, and so
far as I can tell the docs guys listen.
--
Niall Litchfield
Oracle DBA
Audit Commission UK
*****************************************
Please include version and platform
and SQL where applicable
It makes life easier and increases the
likelihood of a good answer
******************************************
Few examples, lots of typos, unprintable (not in PDF, etc), pathetic
indexing. M$ofts bunch should be condemned to paint the bottom of
Bill's -um- ... whatever.
Steve
> Bad? Well, I don't know. Having been absorbed in a SQL Server project
> even the Worst of Oracle is starting to look like poetry when compared
> to M$oft's (cough) 'documentation'.
>
> Few examples, lots of typos, unprintable (not in PDF, etc), pathetic
> indexing. M$ofts bunch should be condemned to paint the bottom of
> Bill's -um- ... whatever.
>
> <snipped>
Well I sail past Bill's house from time-to-time and as near as I can tell he has no
boat. At least not one tied up in Lake Washington. Perhaps they could hire an
architect and turn his bunker into something that actually resembles a house.
But yes. Microsoft's documentation makes Oracle's look like an act of divine
perfection.
>> But yes. Microsoft's documentation makes Oracle's look like an act of
divine
>> perfection.
I had to write a utility in C for out NT gurus a while back. It
basically enumerated all the networks and devices attached, then for
each device, enumerated the shares and then listed the users connected
to those shares and the OS they were using at the time. What a f'ing
nightmare. The MS docs are indeed pathetic and mostly useless. In the
end, the utility came to be known as TBUFH and has a fat pig as an icon.
TBUFH - The B*st*rd Utility From Hell !!
Cheers,
Norman.
PS. On the Borland NGs, the complaints about Borlands docs usually
praise the high quality of Microsoft's docs - it's a funny old world.
-------------------------------------
Norman Dunbar
Database/Unix administrator
Lynx Financial Systems Ltd.
mailto:Norman...@LFS.co.uk
Tel: 0113 289 6265
Fax: 0113 289 3146
URL: http://www.Lynx-FS.com
-------------------------------------
The SQL*plus manual used to have an incorrect listing of operator
precedence (at least as late as 7.3.2). I'm too lazy to see if they
ever fixed it. Some programmers looked at me with wonder when I would
tell them to put parens around certain arithmetic expressions and it
would fix their code.
But my favorite is still the Oracle on SunOS(BSD) install guide with
the SysV installation instructions. Oopsie! Cut'n'Paste is so
productive!
jg
--
@home.com is bogus.
Oopsie?
I've got part of it. The 'Oop' stands for Object Oriented Programming.
What does 'sie' stand for?
why systems integration engineering obviously :(. Or in fact its just an
exclamation when something goes wrong. Though clearly any discipline with a
name like Object Oriented Programmable Systems Integration Engineering is
likely to a) make impressive powerpoint slides and b) fail dismally.
Looking at the 8.1.7 docs, it becomes obvious that the example Daniel
posts is a hangover from earlier documentation. Below is the 817
version, where whoever wrote the block had included a forward-declared
procedure called get_time. If you take a look at the way it is
written, you would assume that the Oracle guys were embarrassed by the
fact that whoever wrote it had never heard of dbms_utility, so they
tried to cover it up in the 9.2 docs but were not thorough enough to
remove all traces of earlier poor code.
1 DECLARE
2 TYPE NumTab IS TABLE OF NUMBER(4) INDEX BY BINARY_INTEGER;
3 TYPE NameTab IS TABLE OF CHAR(15) INDEX BY BINARY_INTEGER;
4 pnums NumTab;
5 pnames NameTab;
6 t1 NUMBER(5);
7 t2 NUMBER(5);
8 t3 NUMBER(5);
9 PROCEDURE get_time (t OUT NUMBER) IS
10 BEGIN SELECT TO_CHAR(SYSDATE,'SSSSS') INTO t FROM dual; END;
11 BEGIN
12 FOR j IN 1..5000 LOOP -- load index-by tables
13 pnums(j) := j;
14 pnames(j) := 'Part No. ' || TO_CHAR(j);
15 END LOOP;
16 get_time(t1);
17 FOR i IN 1..5000 LOOP -- use FOR loop
18 INSERT INTO parts VALUES (pnums(i), pnames(i));
19 END LOOP;
20 get_time(t2);
21 FORALL i IN 1..5000 -- use FORALL statement
22 INSERT INTO parts VALUES (pnums(i), pnames(i));
23 get_time(t3);
24 DBMS_OUTPUT.PUT_LINE('Execution Time (secs)');
25 DBMS_OUTPUT.PUT_LINE('---------------------');
26 DBMS_OUTPUT.PUT_LINE('FOR loop: ' || TO_CHAR(t2 - t1));
27 DBMS_OUTPUT.PUT_LINE('FORALL: ' || TO_CHAR(t3 - t2));
28* END;
SQL> /
Execution Time (secs)
---------------------
FOR loop: 32
FORALL: 3
Link:-
http://download-west.oracle.com/docs/cd/A87860_01/doc/appdev.817/a77069/04_colls.htm#1059
Regards
Adrian
CREATE TABLE coords (x NUMBER, y NUMBER);
CREATE TYPE Pair AS OBJECT (m NUMBER, n NUMBER);
/
DECLARE
TYPE PairTab IS TABLE OF Pair;
pairs PairTab := PairTab(Pair(1,2), Pair(3,4), Pair(5,6));
TYPE NumTab IS TABLE OF NUMBER;
nums NumTab := NumTab(1, 2, 3);
BEGIN
/* The following statement succeeds. */
FORALL i in 1..3
UPDATE coords SET (x, y) = (pairs(i).m, pairs(i).n)
WHERE x = nums(i);
END;
/
I love the comment "The following statement succeeds" when it is
clearly syntactically incorrect and fails miserably. Using collections
of records in FORALL is still not supported in 9.2 and I submitted an
enhancement request for this a long time ago... Quite what the author
of the above was smoking I don't know.
Adrian
Good catch. At least there is a good work-around for the collections not
be supported. I put together the following demo for my student's that does
a pretty good demo. Here it is for the group:
-- demo tables
CREATE TABLE parent (
part_num NUMBER(10),
part_name VARCHAR2(15));
CREATE TABLE child AS
SELECT *
FROM parent
WHERE 1=2;
-- anonymous block to generate 50K records
DECLARE
j PLS_INTEGER := 1;
k parent.part_name%TYPE := 'Transducer';
BEGIN
FOR i IN 1 .. 50000
LOOP
SELECT DECODE(k, 'Transducer', 'Rectifier',
'Rectifier', 'Capacitor',
'Capacitor', 'Knob',
'Knob', 'Chassis',
'Chassis', 'Transducer')
INTO k
FROM dual;
INSERT INTO parent VALUES (j+i, k);
END LOOP;
COMMIT;
END;
/
-- tranditional method
CREATE OR REPLACE PROCEDURE old_way IS
CURSOR p_cur IS
SELECT *
FROM parent;
p_rec p_cur%ROWTYPE;
BEGIN
OPEN p_cur;
LOOP
FETCH p_cur INTO p_rec;
EXIT WHEN p_cur%NOTFOUND;
p_rec.part_num := p_rec.part_num * 10;
INSERT INTO child
(part_num, part_name)
VALUES
(p_rec.part_num, p_rec.part_name);
END LOOP;
COMMIT;
CLOSE p_cur;
END old_way;
/
-- bulk collect with FORALL method
CREATE OR REPLACE TYPE uw_sel_row AS OBJECT (
part_num NUMBER, part_name VARCHAR2(15));
/
CREATE OR REPLACE PROCEDURE new_way IS
TYPE uw_sel_tab IS TABLE OF uw_sel_row;
uw_selection uw_sel_tab;
TYPE PartNum IS TABLE OF parent.part_num%TYPE INDEX BY BINARY_INTEGER;
x PartNum;
TYPE PartName IS TABLE OF parent.part_name%TYPE INDEX BY BINARY_INTEGER;
y PartName;
BEGIN
SELECT part_num, part_name
BULK COLLECT INTO x, y
FROM parent;
FOR i IN x.FIRST .. x.LAST
LOOP
x(i) := x(i) * 10;
END LOOP;
FORALL i IN x.FIRST .. x.LAST
INSERT INTO child
(part_num, part_name)
VALUES
(x(i), y(i));
END new_way;
/
You don't need SET TIMING ON to see the dramatic difference in
performance.
You guys are a riot! :-)
Actually, I wouldn't expect either of you to get the insider
reference, as it is local to SoCal. On Highway 1, just north of Santa
Monica, for years and years there was graffiti on a highly visible
concrete drainage construct halfway up the cliff. Someone drew a big
red and black mushroom cloud and the one word - "Oopsie!"
jg
--
@home.com is bogus.
> <snipped>
>
> Actually, I wouldn't expect either of you to get the insider
> reference, as it is local to SoCal. On Highway 1, just north of Santa
> Monica, for years and years there was graffiti on a highly visible
> concrete drainage construct halfway up the cliff. Someone drew a big
> red and black mushroom cloud and the one word - "Oopsie!"
>
> jg
> --
> @home.com is bogus.
> http://thumb-1a.image.altavista.com/image/16270847
SoCal that's the place that has: "The 18th annual Desert Symposium at California State University's Desert Studies Center at Zzyzx.
(source http://biology.fullerton.edu/facilities/dsc/zzyzx.html).
A Zzyzx beats an Oopsie like a full house beats a pair of deuces.