2024.07.16 oracle函数练习

--8.创建函数,将emp表中工资低于所在部门平均工资的职工工资加上500,并返回修改了工资的总人数:
create or replace function f1 return number is
    v_count number;
begin
    update emp
    set sal = sal + 500
    where sal < (select avg(sal) 
                 from emp e2 
                 where e2.deptno = emp.deptno);
    select count(*)
    into v_count
    from emp
    where sal > (select avg(sal)
                 from emp e2
                 where e2.deptno = emp.deptno
                 group by deptno)
          and sal <= (select avg(sal)
                      from emp e2
                      where e2.deptno = emp.deptno
                      group by deptno) + 500;
    return v_count;
end;
 declare
    v_updated_count number;
begin
    v_updated_count := f1;
    dbms_output.put_line(v_updated_count);
end;


--9.编写函数nvl3(tab_name,column1,column2),遍历某表当某表中任意列一和列二的值相等时,回传列一的值,否则回传列二的值:
--当某表中任意列一和列二的值相等时,回传列一的值,否则回传列二的值:
create or replace type tabs is table of varchar2(300);
create or replace function nvl3(tab_name varchar2,column1 varchar2,column2 varchar2) 
return tabs 
is
  str varchar2(300);
  col1 tabs;
  col2 tabs;
  x number := 0;
begin
  str:='select '||column1||','||column2||' from '||tab_name;
  execute immediate str bulk collect into col1,col2; 
  for i in 1..col1.last loop
    for j in 1..col2.last loop
      if col1(i) = col2(j) then
         x := x+1;
      end if;
    end loop;
  end loop;
  if x > 0 then
    return col1;
  elsif x = 0 then
    return col2;
  end if;
exception
  when others then
    dbms_output.put_line(sqlerrm); 
end;
declare
  s tabs;
begin
  s:=nvl3('emp','empno','mgr');
  for i in 1..s.last loop
    dbms_output.put_line(s(i));
  end loop;
end; 

--10.创建一个函数,它接收调用函数中传递过来的两个实参值:date1、date2,计算两个日期内有多少个工作日(
--假设只在周六周天休息,不算国家法定节假日):
create or replace function cw(
    date1  date,
    date2  date
) return number 
is
    start_date date;
    end_date date;
    wc number := 0;
    current_date date;
begin
    if date1 > date2 then
        start_date := date2;
        end_date := date1;
    else
        start_date := date1;
        end_date := date2;
    end if;
    current_date := start_date;
    while current_date <= end_date loop
        if to_char(current_date,'DY') not in ('SAT', 'SUN') then
            wc := wc + 1;
        end if;
        current_date := current_date + 1;
    end loop;
    return wc;
end;
declare
    v_workdays number;
begin
    v_workdays := cw(to_date('2024-07-01', 'YYYY-MM-DD'), to_date('2024-07-15', 'YYYY-MM-DD'));
    dbms_output.put_line('Number of workdays: '|| v_workdays);
end;
  --11.编写一个函数,传入一个身份证号,计算此人的周岁年龄,并返回此人的性别。输出‘此人xx周岁,性别x。’:
create or replace function idcard (
    i in number
) return varchar2
is
    birth_date date;
    current_date date := sysdate;
    age number;
    sex varchar2(10);
    gender_char char(1);
begin
    birth_date := to_date(substr(i, 7, 8), 'YYYYMMDD');
    age := extract(year from current_date) - extract(year from birth_date);
    if (to_date(extract(year from current_date) || to_char(birth_date, 'MMDD'), 'YYYYMMDD') > current_date) then
        age := age - 1;
    end if;
    gender_char := substr(i, 17, 1);
    if to_number(gender_char) mod 2 = 1 then
        sex := 'male';
    else
        sex := 'female';
    end if;
    return '此人' || age || '周岁,性别' || sex || '。';
end;

declare
    v_result varchar2(100);
begin
    v_result := idcard('123456199001015678'); -- 示例身份证号
    dbms_output.put_line(v_result);
end;

--12.创建一个函数,传入一个字符串,提取字符串中的数字,如果没有数字则返回 -1:
create or replace function st (
    s in varchar2
) return number
is
    exnum varchar2(4000) := ''; 
    ch char(1);
begin
    for i in 1 .. length(s) loop
        ch := substr(s, i, 1);
        if ch between '0' and '9' then
            exnum := exnum || ch;
        end if;
    end loop;
    if exnum is not null then
        return to_number(exnum);
    else
        return -1;
    end if;
end;

 declare
    v_result number;
begin
    v_result := st('abc123def456'); 
    dbms_output.put_line(v_result); 

    v_result := st('qwe');
    dbms_output.put_line(v_result); 
end;
--13.编写一个函数,可以实现输入其中带‘,’的字符串‘1,2,3,a,b,c’,把用‘,’分隔的内容分割成多行显示:
create or replace function f1 (
    newline in varchar2
) return varchar2
is
begin
    return replace(newline, ',', chr(10));
end;

declare 
s varchar(400);
begin
  s:=f1('1,2,3,a,b,c,qwertyuiop,123456+');
  dbms_output.put_line(s);
end;

       
--14.函数说明:字符串按照指定分隔符拆分,截取第几个部位:
/*
参数1:v_str 要分割的字符串,例:‘1-36-47-599-3-0’
参数2:v_cut 分隔符,例:‘-’
参数3:v_index 取第几个元素,例:‘3’
*/

create or replace function f1 (
    v_str    in varchar2,
    v_cut    in varchar2,
    v_index  in number
) return varchar2
is
    v_result varchar2(4000);
    v_temp   varchar2(4000);
    v_count  number := 0;
    v_start  number := 1;
    v_pos    number;
begin
    v_result := null;
    v_temp := v_str;
    while length(v_temp) > 0 loop
        v_pos := instr(v_temp, v_cut);
        if v_pos > 0 then
            v_result := substr(v_temp, 1, v_pos - 1);
            v_temp := substr(v_temp, v_pos + length(v_cut));
        else
            v_result := v_temp;
            v_temp := '';
        end if;
        v_count := v_count + 1;
        if v_count = v_index then
            return v_result;
        end if;
    end loop;
    return null;
end;

--15.编写一函数,完成下面的功能:
/*
1.输入姓名,课程名,成绩。该过程完成对SC表的插入或修改操作;
2.若插入成功,返回成功信息;
3.若该选课信息已经存在,则修改其成绩为输入的成绩;
4.若遇系统错误,返回相关错误信息。
*/

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值