第四章 存储过程 难题 ,烧脑哦........

创建一个存储过程,输入一个带若干逗号的字符串,输出用逗号分隔的字符串信息


方式一:

create or replace procedure pro_getchar(v_char in varchar2)
is
n number;–逗号个数
i number:=1;–为了求出逗号个数而设置的循环变量
p1 number;–前一个逗号的位置
p2 number;–后一个逗号的位置
single_char varchar2(200);–承接要输出的单个字符串
begin
–字符串中第一个字符开始1次出现逗号的位置数字信息
select instr(v_char,’,’,1,1) into p1 from dual;
– 从1开始,截取p1-1个长度后的字符串
select substr(v_char,1,p1-1) into single_char from dual;
–输出第一个逗号前面的字符串
dbms_output.put_line(single_char);
while p1!=0 loop
select instr(v_char,’,’,1,i) into p1 from dual;
if p1=0 then
n:=i-1;–统计出逗号的个数,作为输出中间字符串个数的循环变量范围下限
end if;
i:=i+1;
end loop;
for j in 1..n-1 loop–循环输出第一个逗号和最后一个逗号之间的每个字符串
select instr(v_char,’,’,1,j) into p1 from dual;
select instr(v_char,’,’,1,j+1) into p2 from dual;
select substr(v_char,p1+1,p2-p1-1) into single_char from dual;
dbms_output.put_line(single_char);
end loop;
select instr(v_char,’,’,1,n) into p1 from dual;
select substr(v_char,p1+1,length(v_char)-p1) into single_char from dual;
–输出最后一个逗号后面的字符串
dbms_output.put_line(single_char);
exception –没有逗号 就是输出单个字符串
when others then dbms_output.put_line(v_char);
end;
存储过程已创建,调用:
begin
pro_getchar(‘ad135351d,wwew,df2.1.d,asd12.12a,asdf135eeg,j13ghhj,3513tg’);
end;
调用二:
declare
v1 varchar2(200):=’&inputchar’;
begin
pro_getchar(v1);
end;


方式二:

——————朱老师:方式二————————-
create or replace procedure
getchar(mystr varchar2)
is
s_count number;
s_position number;–本次逗号出现的位置
s_oldposition number;–上次逗号出现的位置
begin
– 得到字符串中逗号的数量
select length(mystr)-length(replace(mystr,’,’,”))
into s_count from dual;
if s_count=0 then
–如果输入的字符串中没有逗号,直接输出
dbms_output.put_line(mystr);
else
for i in 1.. s_count loop
–循环过程中i表示的是逗号出现的次数
s_position := instr(mystr,’,’,1,i);
if i>=2 and i<=s_count then
s_oldposition:= instr(mystr,’,’,1,i-1);
end if;
if i=1 and s_position!=1 then
–如果该字符串是第一个逗号前的字符串信息
dbms_output.put_line(substr(mystr,1,s_position-1));
–如果只有一个逗号
if s_count =1 then
dbms_output.put_line(substr(mystr,s_position+1));
end if;
elsif i>1 then
–1,2,err,ew
dbms_output.put_line
(substr(mystr,s_oldposition+1,
s_position-s_oldposition-1));
if i=s_count then
–输出最后一个逗号之后的字符串信息
dbms_output.put_line(substr(mystr,s_position+1));
end if;
end if;
end loop;
end if;
end;

—————–刘丽梅:方式三————————–
create or replace procedure
pro_varchar(p_varchar varchar2)
is
v_varchar varchar2(100);
begin
v_varchar :=p_varchar;
if instr(p_varchar,’,’)<>0 then
for n in 1..(length(p_varchar)-
length(replace(p_varchar,’,’,”))) loop
–取v_varchar中逗号第一次出现之前的信息
dbms_output.put_line(substr(v_varchar,
1,instr(v_varchar,’,’,1)-1));
– 1ss,ss,ddd,dd
–将字符串左侧的已经输出的信息去除掉
v_varchar:=ltrim(p_varchar,
substr(p_varchar,1,instr(p_varchar,’,’,1,n)));
if instr(v_varchar,’,’)=0 then
dbms_output.put_line(v_varchar);
end if;
end loop;
else dbms_output.put_line(v_varchar);
end if;
end;

—————–梁小荣:方式四————————–

create or replace procedure we1 (p_char in varchar2)
as
w varchar2(20);
e varchar2(20);
f varchar2(20);
q varchar2(20);
var varchar2(20);
begin
var :=p_char;
select length(p_char)-length(replace(p_char,’,’,”)) into q from dual;
–www,hhhh,jjj
for a in 1..q loop
select instr(p_char,’,’,1,a) into w from dual;
select substr(p_char,w) into e from dual;
select replace(var,e,”) into f from dual;
dbms_output.put_line(f);
var:=e;
var:=ltrim(var,’,’);

end loop;

select instr(p_char,’,’,1,q) into w from dual;
select substr(p_char,w+1) into f from dual;
dbms_output.put_line(f);
end;

———————华夏: 方式五————————–

create or replace procedure av(v_string in varchar2)
as
i number :=1;
j number :=1;
num number;
loc number;
str varchar2(1000);
begin
num := instr(v_string,’,’,1,j);
if num= 0 then
str := substr(v_string,i);
dbms_output.put_line(str);
else loop
–逗号在第j次出现的位置
loc := instr(v_string,’,’,1,j);
if loc > 0 then
str := substr(v_string,i,loc-i);
dbms_output.put_line(str);
–逗号在第j次出现的位置
i:=loc+1;
j:=j+1;
else str := substr(v_string,i);
dbms_output.put_line(str);
exit when loc= 0;
end if;
end loop;
end if;
end;
call av(‘japm,asd,’);

———-补充的,套入存储过程即可:方式六————-

SELECT NVL(REGEXP_SUBSTR(‘17,20,23’,
‘[^,]+’, 1, LEVEL, ‘i’), ‘NULL’)
AS STR
FROM DUAL
CONNECT BY LEVEL <=length(‘17,20,23’)
-length(replace(‘17,20,23’,’,’,”))+1 ;

==========================================
select ascii(‘A’),chr(65),chr(10) from dual; chr 函数了解

–2、创建一个存储过程,取出连续三天的信息
create table time_table (datetime date);
insert into time_table values(to_date(‘20180718’,’yyyymmdd’));
commit;

create or replace procedure pro_threeday
as
day1 date;
day2 date;
day3 date;
v_count number;
begin
select count(*) into v_count from time_table;
for i in 1..v_count loop
select datetime into day1 from
(select rownum rn,t1.* from
(select * from time_table order by datetime) t1) t2
where t2.rn=i;
select datetime into day2 from
(select rownum rn,t1.* from
(select * from time_table order by datetime) t1) t2
where t2.rn=i+1;
select datetime into day3 from
(select rownum rn,t1.* from
(select * from time_table order by datetime) t1) t2
where t2.rn=i+2;
if day2-day1=1 and day3-day2=1 then
dbms_output.put_line(to_char(day1,’yyyy-mm-dd’));
dbms_output.put_line(to_char(day2,’yyyy-mm-dd’));
dbms_output.put_line(to_char(day3,’yyyy-mm-dd’));
end if;
end loop;
end;
存储过程已创建,调用:
call pro_threeday();

select * from time_table order by datetime;

———–朱老师 方式二:———————–
select begin_dt
from (select begin_dt,
count(*) over(partition by ch) cnt
from
(select begin_dt,
to_date(begin_dt, ‘yyyy-mm-dd’)
- dense_rank() over(order by
begin_dt) ch
from liur_account)
)
where cnt >= 3;

要点说明:
dense_rank() over(order by begin_dt) 根据begin_dt日期大小排序,然后取数据的行号;
to_date(begin_dt, ‘yyyy-mm-dd’) - dense_rank() over(order by begin_dt) ch 用日期减去行号,得到一列日期格式的值,如果日期是连续的,得到的日期值将是一样的;
count(*) over(partition by ch)cnt 根据以上减去的结果分组,每行做一次count;

猜你喜欢

转载自blog.csdn.net/weixin_42800008/article/details/81346714
今日推荐