|
还可以进一步。
1. dbms_sql.varchar2s 有可替代的吗?
select NAME,text from dba_source
where upper(text) like '%TABLE%VARCHAR%INDEX%'
order by length(NAME)
OWA type nc_arr is table of nvarchar2(16000) index by binary_integer;
用 OWA.vc_arr 又省8个字节
2. subtype varchar(999) 有可替代的吗?
select NAME,text from dba_source
where upper(text) like '%SUBTYPE%CHAR%'
order by length(NAME)
LONG/RAW/ROWID 都无法进行隐式转换至 number, string可以。
subtype v is STRING(999);
省一个。
最终1131
- CREATE OR REPLACE PACKAGE BODY EASTER is
- -- Point 0: 1个table保存N种数据
- -- 数据1. 某一年对应的dateindex
- -- dateindex计算方式
- -- 20 for 3/21
- -- 3月
- -- 日期 - 1
- -- 3/22 = 21
- -- 3/31 = 30
- -- 四月
- -- 日期 + 30
- -- 4/1 = 1+30 = 31
- -- 4/25 = 25+30 = 55
- -- 数据2. 日期重复数,保存为负数
- -- 数据3. 日期对应的("MM-DD") 输出,索引为-dateindex
- -- 数据4. 通过ceil(dateindex/30), 分别用s(1)代表3月份,s(2)代表4月份重复数,同时记为负数,参考nyfor
- -- Point 1: 用 dbms_sql.varchar2s 代替 dbms_sql.number_table
- --S utl_http.vc2_table;
- --S dbms_sql.varchar2s;
- --S htp.htbuf_arr;
- S OWA.vc_arr;
- -- Point 2: 用 subtype, 参考某人,具体忘了,不好意思
- subtype v is STRING(999);
- --subtype v is VARCHAR(999);
- -- Point 3: 共享的local 变量,多次使用
- N v;
- m v;
- -- Point 4: Function o, 代替 dbms_output.put_line,用两个变量,避免其他地方大量的||' '||操作符
- procedure o(l v,k v:='') as
- begin
- dbms_output.put_line(l||' '||k);
- --Package初始化,放在这里省一个begin,参考nyfor
- --begin
- for i in 1..61 loop
- s(i):=0;
- --用date'1-3-1' 代替to_date(...),参考某人,具体忘了,不好意思
- s(-i):=to_char(date'1-3-1'+i,'MM-DD');
- end loop;
- -- Caculate EASTER date for certain year(1900-2099)
- -- Return a date interval compare to 3/31
- -- Return 1 for 3/22, 11 for 4/1 etc.
- -- Point 6,combine the expression
- --Reuse M/N
- --N int;
- --Q int;
- --B int;
- --M int;
- --W int;
- for Y in 2011..2099 loop
- --N:=Y-1900;
- --A:=mod(N,19);
- --Q:=floor(N/4);
- --B:=floor((7*mod(N,19)+1)/19);
- --M:=mod(11*A+4-B,29);
- -- a mod b 代替 mod(a,b), 参考某人,具体忘了,不好意思
- N:=Y mod 19;
- N:=(11*N+4-floor((7*N+1)/19)) mod 29;
- --W:=mod(N+floor(N/4)+31-M,7);
- --return 25-M-W;
- -- -2344 = -1900-1900/4+31 , 参考nyfor
- N:=55-N-(Y-6+floor(Y/4)-N) mod 7;
- s(Y):=N;
- -- Previos count in the EASTER date+1
- -- o(s(n));
- s(N):=s(N)-1;
- --用上下标代替if/else, 参考nyfor
- M:=ceil(N/30);
- s(M):=least(+s(M),s(N));
- end loop;
- --把临时变量设为null
- N:='';
- end;
- procedure showAllEasterDay as
- begin
- --Header
- o('YEAR DAY');
- for Y in 2011..2099 loop
- o(Y,s(-s(y)));
- end loop;
- end;
- -- 最大重复数
- procedure showMaxOccurenceEasterDay as
- procedure u(x v,y v,z v:=55) as
- begin
- for i in y..z loop
- if s(i)=x then
- N:=N||s(-i)||'/' ;
- end if;
- end loop;
- --c:=replace(c||x,'/-',' ')||' ';
- N:=rtrim(N,'/')||' '||-x||' ';
- --c:=substr(c,2)||' '||-x||' ';
- end;
- begin
- o('MAXOCC MO_CNT MAXOCC_3 MO3_CNT MAXOCC_4 MO4_CNT');
- -- 所有最大重复
- u(least(+s(1),s(2)),9);
- --3月最大重复
- u(s(1),9,30);
- --4月最大重复
- u(s(2),31);
- --输出
- o(N);
- end;
- procedure showLeapEasterDay as
- begin
- --Header
- o('ABSENT_START ABSENT_END');
- --ABSENT Begin data
- --21=22-1 = 3/22, 55=25+30 = 4/25
- for i in 21..55 loop
- -- o(s(i)||' '||s(-i));
- if s(i)=0 then
- --Start of ABSENT
- N:=nvl(N,i);
- end if;
- -- 合并判断,参考nyfor
- --Point 10: N>0 to replace "N is not null"
- if i = 55 + N - N or s(i + 1) < N - N then
- o(s(-N),s(-i));
- --start over,N set to null
- -- N:='';
- end if;
- end loop;
- end;
- --show Fool Easter Day
- procedure showFoolEasterDay as
- begin
- -- Caculate Occurence Easter Day
- --Header
- o('YEAR TOTAL');
- for Y in 2011..2099 loop
- -- if F(Y)=4/1,output,get total cnt from S(31),31=30+1
- if s(Y)=31 then
- -- Ponit 11, get total April-1 count from pre-caculated Occurence Easter Day:S.
- o (Y,-s(31));
- end if;
- end loop;
- end;
- end;
- /
复制代码 |
|