Oracle数据库使用小技巧

oracle查询某个字段无查询结果时返回0

场景:
根据khbh查询数据库中的记录,如果无查询结果集,需要返回0给前端。如果使用mybatis查询无结果集会默认返回null给前端,这里可以使用业务代码返回,也可以使用sql操作

查询数据库中不存在的数据返回的结果集为:
在这里插入图片描述

解决

select nvl(sum(t.ea_message_remind),0) ea_message_remind,nvl(sum(t.eo_message_remind),0) eo_message_remind from t_kh_jlcsz t where khbh = '17';

在这里插入图片描述

判null处理

-- varchar2 类型
if v_fwpj is not null and v_fwpj != '满意' then
    
end If;

-- int 类型
if v_zxthsc > 0 then
  nb_sql := nb_sql || ' and  h.thsc >=  '||v_zxthsc;
end if;

游标

游标是指向此上下文区域的指针。PL/SQL通过游标控制上下文区域,游标保存SQL语句返回的行(一个或多个)。 游标所在的行集称为活动集。
可以命名一个游标,以便在程序中引用它来获取和处理SQL语句返回的行,一次处理一个(行)。PL/SQL中有两种类型的游标

隐式游标

当执行SQL语句时,如果语句没有显式游标,则Oracle会自动创建隐式游标。程序员无法控制隐式游标及其信息。

每当发出DML语句(INSERT,UPDATE和DELETE)时,隐式游标与此语句相关联。 对于INSERT操作,游标保存需要插入的数据。对于UPDATE和DELETE操作,游标标识将受到影响的行。

在PL/SQL中,可以将最近的隐式游标引用SQL游标,它始终具有%FOUND%ISOPEN%NOTFOUND%ROWCOUNT等属性。 SQL游标具有额外的属性%BULK_ROWCOUNT和%BULK_EXCEPTIONS,旨在与FORALL语句一起使用。下表提供了游标中最常用属性的描述 -

属性描述
%FOUND如果INSERT,UPDATE或DELETE语句影响一行或多行,或老兄SELECT INTO语句返回一行或多行,则返回TRUE,否则返回FALSE。
%NOTFOUND与%FOUND的逻辑相反。 如果INSERT,UPDATE或DELETE语句没有影响任何行,或SELECT INTO语句未返回任何行,则返回TRUE。 否则返回FALSE。
%ISOPEN由于Oracle在执行关联的SQL语句后会自动关闭SQL游标,因此总是为隐式游标返回FALSE。
%ROWCOUNT返回受INSERT,UPDATE或DELETE语句,或者受SELECT INTO语句影响的行数
任何SQL游标属性将被访问为sql%属性

显式游标

显式游标是用于获得对上下文区域的更多控制的程序员定义的游标。应在PL/SQL块的声明部分中定义一个显式游标。它是在一个返回多行的SELECT语句中创建的。

使用显式游标包括以下步骤
1、声明游标初始化内存 (cursor v_cursor is select * from aaa;)
2、打开游标分配内存 (open v_cursor; )
3、从游标获取数据 ( fetch v_cursor into v_row;)
4、关闭游标以释放分配的内存 (close v_cursor;)

declare 
  cursor v_cursor is select * from aaa; --1.声明游标
  v_row aaa%rowtype; --2. 声明变量v_row,变量类型为aaa表的一行
begin
  open v_cursor;  --3.打开游标
  loop --4、使用 loop 循环遍历游标
    fetch v_cursor into v_row;   --5、遍历游标 v_cursor 的每一行结果给(into)变量v_row
    exit when v_cursor%notfound;  --6、当游标 v_cursor 没有再读取到值时,则退出循环 
    --dbms_output.put_line():plsql 的输出语句
    dbms_output.put_line('ywlxmc'||v_row.ywlxmc ||' thcs: ' ||v_row.thcs||' ywlxcj: ' ||v_row.ywlxcj ||' thszb: ' ||v_row.thszb );
  end loop;
  close v_cursor;
end;
declare
   cursor v_cursor(v_thcs number) is select * from aaa where thcs = v_thcs;
   v_row aaa%rowtype; 
begin
   open v_cursor(55);
   loop
     fetch v_cursor into v_row;
     if v_cursor%notfound then
       exit;
     end if;
     dbms_output.put_line('证券:'|| v_row.ywlxmc  || ' thcs:'|| v_row.thcs);
   end loop;
   close v_cursor;
end;

使用系统游标显示定义

declare 
   v_sys_cursor sys_refcursor;
   v_row aaa%rowtype;
begin
   open v_sys_cursor for select * from aaa;
   loop 
     fetch v_sys_cursor into v_row;
     exit when v_sys_cursor%notfound;
     dbms_output.put_line('证券:'|| v_row.ywlxmc  || ' thcs:'|| v_row.thcs);
   end loop;
   close v_sys_cursor;
end;

使用for遍历游标,可以自动关闭游标

declare
  cursor v_cursor is select * from aaa;
begin
  for v_row in v_cursor loop
    dbms_output.put_line('证券:'|| v_row.ywlxmc  || ' thcs:'|| v_row.thcs);
  end loop;
end;

异常

异常处理函数用于取得Oracle错误号和错误信息,其中:

  • 函数SQLCODE用于取得错误号
  • SQLERRM用于取得错误信息。

RAISE_APPLICATION_ERROR该函数用于在PL/SQL子程序中自定义错误信息。
语法格式:raise_application_error(error_number,message)
1、error_number:用于定义错误号(-20000-20999)
2、message:用于指定错误信息,长度不能超过2048个字节

优雅抛出异常消息

-- 根据客户编号查询记录,如果存在及修改,如果不存在及新增
create or replace procedure up_mid_99400001(
  v_khbh           varchar2,       --  客户编号
  v_ea_message_remind        varchar2,       -- 是否开启消息提醒(默认不提醒0/1提醒)
  v_eo_message_remind         varchar2,       -- 消息提醒是否自动关闭(默认自动关闭0/1开启)
  rc1             out           jz_oraoledb.m_refcur,
  rc2             out           jz_oraoledb.m_refcur
)
as
  -- v_result sys_refcursor;
  nb_errormsg varchar2(200);
  v_result varchar2(40);
begin
    select count(*) into v_result from t_kh_jlcsz  where khbh = v_khbh;
    if v_result=0 then
       insert into t_kh_jlcsz(khbh,ea_message_remind,eo_message_remind)
       values(v_khbh,v_ea_message_remind,v_eo_message_remind);
       commit;
       open rc1 for select  0 as errorcode, '新增成功!' as errormsg from dual;
       open rc2 for select  0 as errorcode, '新增成功!' as errormsg from dual;
    else
      update t_kh_jlcsz set
            ea_message_remind =  v_ea_message_remind,
            eo_message_remind = v_eo_message_remind where khbh = v_khbh;
            commit;
      open rc1 for select  0 as errorcode, '修改成功!' as errormsg from dual;
      open rc2 for select  0 as errorcode, '修改成功!' as errormsg from dual;
    end if;

exception when others then
  -- SQLERRM用于取得错误信息。
  nb_errormsg := substr(sqlerrm,1,200);
  -- 函数SQLCODE用于取得错误号
  open rc1 for select  -123456 as errorcode, '业务操作异常!'||nb_errormsg as errormsg from dual;
  open rc2 for select  -123456 as errorcode, '业务操作异常!'||nb_errormsg as errormsg from dual;
end up_mid_99400001;

在这里插入图片描述

自定义异常

1、第一方式自定义异常

declare 
   cursor v_cursor is select * from aaa ;
   number_exception exception;
begin
   for v_row in v_cursor loop
       exit when v_cursor%notfound;
       case v_row.thcs
         when 203 then dbms_output.put_line('203');    
         when 563 then dbms_output.put_line('563');  
         when 632 then dbms_output.put_line('632');
         when 55 then raise number_exception;
       end case;
   end loop;    
exception
  when number_exception then dbms_output.put_line('数据出错了');
end;

2、第二种方式创建自定义异常

-- 创建存储过程
create or replace procedure change_sal(eno number,salary number)
is 
begin
  update emp set sal = salary where empno=eno;
  if sql%notfound then
    raise_application_error(-20002,'该员工不存在!');
  else
    dbms_output.put_line('更新成功!');
    commit;
  end if;
end;
 
-- 执行存储过程
begin
  change_sal(8888,800);
end;

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李熠漾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值