|
|
要精细控制,还似乎要用过程语言,不能用用户控制不了的SQL
几个有效的改进,还能把b(j)的上界再缩短,避免判断a(i)+b(j)>=1000
create or replace procedure pc3
as
time_before BINARY_INTEGER;
time_after BINARY_INTEGER;
TYPE t_num IS TABLE OF VARCHAR2(3) INDEX BY PLS_INTEGER ;
x t_num;
a t_num;
b t_num;
c PLS_INTEGER;
c1 PLS_INTEGER;
begin
c:=0;
time_before := DBMS_UTILITY.GET_TIME;
for i in 123..987 loop
if substr(i,1,1)<>substr(i,2,1)and
substr(i,2,1)<>substr(i,3,1)and
substr(i,1,1)<>substr(i,3,1)and
instr(i,0)=0 then
c:=c+1;
if i<500 then
a(c):=i;
c1:=c;
end if;
b(c):=i;
x(i):=c;
end if;
end loop;
for k in 1 ..3 loop
FOR I IN 1 .. c1 LOOP
FOR J IN x(a(i))+1 .. c LOOP
if /*a(i)<500 and a(i)<b(j) and*/ a(i)+b(j)<1000 and translate('123456789','$'||a(i)||b(j)||(a(i)+b(j)),'$')is null then
--dbms_output.put_line(a(i)||b(j)||(a(i)+b(j)));
NULL;
--elsif a(i)>=500 then --0.42s
-- goto l_end;
elsif a(i)+b(j)>=1000 then --0.41s
goto next_j;
end if;
end loop;
<<next_j>>
null;
end loop;
<<l_end>>
null;
end loop;
time_after := DBMS_UTILITY.GET_TIME;
DBMS_OUTPUT.PUT_LINE ('output:'||(time_after - time_before));
end;
/
SQL> create or replace procedure pc
2 as
3 time_before BINARY_INTEGER;
4 time_after BINARY_INTEGER;
5 TYPE t_num IS TABLE OF VARCHAR2(3) INDEX BY PLS_INTEGER ;
6 a t_num;
7 b t_num;
8 c PLS_INTEGER;
9 begin
10 c:=0;
11 time_before := DBMS_UTILITY.GET_TIME;
12 for i in 123..987 loop
13 if substr(i,1,1)<>substr(i,2,1)and
14 substr(i,2,1)<>substr(i,3,1)and
15 substr(i,1,1)<>substr(i,3,1)and
16 instr(i,0)=0 then
17 c:=c+1;
18 a(c):=i;
19 b(c):=i;
20 end if;
21 end loop;
22 for k in 1 ..3 loop
23 FOR I IN 1 .. c LOOP
24 FOR J IN 1 .. c LOOP
25 if a(i)<500 and a(i)+b(j)<1000 and a(i)<b(j) and translate('123456789','$'||a(i)||b(j)||(a(i)+b(j)),'$')is null then
26 --dbms_output.put_line(a(i)||b(j)||(a(i)+b(j)));
27 NULL;
28 end if;
29 end loop;
30 end loop;
31 end loop;
32 time_after := DBMS_UTILITY.GET_TIME;
33 DBMS_OUTPUT.PUT_LINE ('output:'||(time_after - time_before));
34 end;
35 /
过程已创建。
已用时间: 00: 00: 00.07
SQL> set serverout on
SQL> exec pc;
output:180
PL/SQL 过程已成功完成。
已用时间: 00: 00: 01.08
SQL> /
过程已创建。
已用时间: 00: 00: 00.01
SQL> exec pc;
output:175
PL/SQL 过程已成功完成。
已用时间: 00: 00: 01.07
SQL> create or replace procedure pc1
2 as
3 time_before BINARY_INTEGER;
4 time_after BINARY_INTEGER;
5 TYPE t_num IS TABLE OF VARCHAR2(3) INDEX BY PLS_INTEGER ;
6 a t_num;
7 b t_num;
8 c PLS_INTEGER;
9 begin
10 c:=0;
11 time_before := DBMS_UTILITY.GET_TIME;
12 for i in 123..987 loop
13 if substr(i,1,1)<>substr(i,2,1)and
14 substr(i,2,1)<>substr(i,3,1)and
15 substr(i,1,1)<>substr(i,3,1)and
16 instr(i,0)=0 then
17 c:=c+1;
18 a(c):=i;
19 b(c):=i;
20 end if;
21 end loop;
22 for k in 1 ..3 loop
23 FOR I IN 1 .. c LOOP
24 FOR J IN 1 .. c LOOP
25 if a(i)<500 and a(i)+b(j)<1000 and a(i)<b(j) and translate('123456789','$'||a(i)||b(j)||(a(i)+b(j)),'$')is null then
26 --dbms_output.put_line(a(i)||b(j)||(a(i)+b(j)));
27 NULL;
28 elsif a(i)>=500 then --0.42s
29 goto l_end;
30 elsif a(i)+b(j)>=1000 then --0.41s
31 goto next_j;
32 end if;
33 end loop;
34 <<next_j>>
35 null;
36 end loop;
37 <<l_end>>
38 null;
39 end loop;
40
41 time_after := DBMS_UTILITY.GET_TIME;
42 DBMS_OUTPUT.PUT_LINE ('output:'||(time_after - time_before));
43 end;
44 /
过程已创建。
已用时间: 00: 00: 00.00
SQL> exec pc1;
output:171
PL/SQL 过程已成功完成。
已用时间: 00: 00: 01.07
SQL> create or replace procedure pc2
2 as
3 time_before BINARY_INTEGER;
4 time_after BINARY_INTEGER;
5 TYPE t_num IS TABLE OF VARCHAR2(3) INDEX BY PLS_INTEGER ;
6 a t_num;
7 b t_num;
8 c PLS_INTEGER;
9 c1 PLS_INTEGER;
10 begin
11 c:=0;
12 time_before := DBMS_UTILITY.GET_TIME;
13 for i in 123..987 loop
14 if substr(i,1,1)<>substr(i,2,1)and
15 substr(i,2,1)<>substr(i,3,1)and
16 substr(i,1,1)<>substr(i,3,1)and
17 instr(i,0)=0 then
18 c:=c+1;
19 if i<500 then
20 a(c):=i;
21 c1:=c;
22 end if;
23 b(c):=i;
24 end if;
25 end loop;
26 for k in 1 ..3 loop
27 FOR I IN 1 .. c1 LOOP
28 FOR J IN 1 .. c LOOP
29 if /*a(i)<500 and*/ a(i)+b(j)<1000 and a(i)<b(j) and translate('123456789','$'||a(i)||b(j)||(a(i)+b(j)),'$')is null then
30 --dbms_output.put_line(a(i)||b(j)||(a(i)+b(j)));
31 NULL;
32 --elsif a(i)>=500 then --0.42s
33 -- goto l_end;
34 elsif a(i)+b(j)>=1000 then --0.41s
35 goto next_j;
36 end if;
37 end loop;
38 <<next_j>>
39 null;
40 end loop;
41 <<l_end>>
42 null;
43 end loop;
44
45 time_after := DBMS_UTILITY.GET_TIME;
46 DBMS_OUTPUT.PUT_LINE ('output:'||(time_after - time_before));
47 end;
48 /
过程已创建。
已用时间: 00: 00: 00.00
SQL> exec pc2;
output:158
PL/SQL 过程已成功完成。
已用时间: 00: 00: 01.05
SQL> exec pc2;
output:158
PL/SQL 过程已成功完成。
已用时间: 00: 00: 01.05
SQL> create or replace procedure pc3
2 as
3 time_before BINARY_INTEGER;
4 time_after BINARY_INTEGER;
5 TYPE t_num IS TABLE OF VARCHAR2(3) INDEX BY PLS_INTEGER ;
6 x t_num;
7 a t_num;
8 b t_num;
9 c PLS_INTEGER;
10 c1 PLS_INTEGER;
11 begin
12 c:=0;
13 time_before := DBMS_UTILITY.GET_TIME;
14 for i in 123..987 loop
15 if substr(i,1,1)<>substr(i,2,1)and
16 substr(i,2,1)<>substr(i,3,1)and
17 substr(i,1,1)<>substr(i,3,1)and
18 instr(i,0)=0 then
19 c:=c+1;
20 if i<500 then
21 a(c):=i;
22 c1:=c;
23 end if;
24 b(c):=i;
25 x(i):=c;
26 end if;
27 end loop;
28 for k in 1 ..3 loop
29 FOR I IN 1 .. c1 LOOP
30 FOR J IN x(a(i))+1 .. c LOOP
31 if /*a(i)<500 and a(i)<b(j) and*/ a(i)+b(j)<1000 and translate('123456789','$'||a(i)||b(j)||(a(i)+b(j)),'$')is null then
32 --dbms_output.put_line(a(i)||b(j)||(a(i)+b(j)));
33 NULL;
34 --elsif a(i)>=500 then --0.42s
35 -- goto l_end;
36 elsif a(i)+b(j)>=1000 then --0.41s
37 goto next_j;
38 end if;
39 end loop;
40 <<next_j>>
41 null;
42 end loop;
43 <<l_end>>
44 null;
45 end loop;
46
47 time_after := DBMS_UTILITY.GET_TIME;
48 DBMS_OUTPUT.PUT_LINE ('output:'||(time_after - time_before));
49 end;
50 /
过程已创建。
已用时间: 00: 00: 00.00
SQL> exec pc3;
output:136
PL/SQL 过程已成功完成。
已用时间: 00: 00: 01.03
SQL> exec pc3;
output:138
PL/SQL 过程已成功完成。
已用时间: 00: 00: 01.03
SQL> |
|