加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Oracle PL/SQL 入门

发布时间:2020-12-12 15:29:03 所属栏目:百科 来源:网络整理
导读:===================================== ====== PL/SQL ========== ============ ============= 语法: [declare] --定义变量,游标,例外 begin --pl/sql程序体 [exception] --处理异常 end; --分号 -----------------------------------------------------
===================================== ====== PL/SQL ========== =========================
语法:
[declare] --定义变量,游标,例外 begin --pl/sql程序体 [exception] --处理异常 end;--分号
-----------------------------------------------------------------------------------------------------------------------------------
declare inumber:=1; --orcale中使用:=进行变量赋值 PIconstant3.14; --常量的关键字 pempemp%rowtype; --记录型变量(存放了表中的一个行数据) pnameemp.ename%type;--引用型变量(引用了表中某一列的类型) begin i:=i+1; dbms_output.put_line('i的值是:'||i); --PI:=PI+1;--报错 dbms_output.put_line(PI); select*intopempfromempwhereempno=7369; '员工的编号:'||pemp.empno||'姓名:'||pemp.ename); selectenameintopname7499; '7499的姓名:'||pname); end;

======================= ========= ====== if ========== ========================================== 语法:
if条件then 语句; elsif条件then else 语句 endif;

有 if 就要有 end if;
--从控制台接收数字,如果是1则输出:我是1
declare pnumnumber:=&pnum;--&表示从控制台接收参数 begin ifpnum=1then dbms_output.put_line('我是1'); endif; end;
declare number:=&pnum; begin else '我是:'||pnum); --从控制台接收年龄, --如果年龄在18岁以下,输出未成年人。 --18~40成年人40以上老年人
agenumber:=&age; ifage<18'未成年'); elsifage>=andage<40then--注意oracle中用的是elsif '成年人'); else '老年人');

========================================== loop ============================================
语法1:
while条件loop 循环体。。。 endloop;
语法2:(常用)
loop exitwhen退出循环的条件; endloop;
for变量(i)in范围(1..10)loop
i1; begin whilei<=10loop dbms_output.put_line(i); i:=i+loop; ;
--使用语法2在控制台打印输出1~10(掌握)
exitwheni>10; --使用语法3在控制台打印输出1~10
foriin1..10 end;
======================================= 游标<光标> ================================== === /* 游标:就是oracle中存放一个结果集 声明语法: cursor游标名称is查询语句; 使用游标: open游标名称;--打开游标 loop--循环遍历数据 fetch游标名称into变量(记录型变量); exitwhen游标%notfound; endloop; close游标名称; */ --输出所有的员工信息(光标实现)
cursorpcisfromemp; pempemp%rowtype; openpc; loop fetchpcintopemp; whenpc%notfound; dbms_output.put_line(pemp.empno||'--'||pemp.ename); loop; closepc; --输出指定部门的员工信息 -- 给游标指定参数
cursorpc(dnonumber)wheredeptno=dno; openpc(20); dbms_output.put_line(pemp.ename||'--'||pemp.empno);

======================================= 异常 ======== == ========== ==== =========== ===
i1; begin i:=5/0; --i:='abc'; exception--处理异常 whenzero_dividethen dbms_output.put_line('除数不能是0'); whenvalue_error'设置错误'); whenothers'其他异常'); ;
--使用记录型变量存放多条数据
pempemp%rowtype; fromemp; exception whentoo_many_rows'返回多条记录'); --查询部门编号为50的员工 --自定义异常
cursorpcisselect*fromempwheredeptno=50; no_emp_dataexception; ifpc%notfoundraiseno_emp_data;---抛出一个异常 if; closepc; exception whenno_emp_data'没有发现员工信息'); ;


========================================= 存储过程 ======== ==============================

定义:定义了一段pl/sql程序,事先编译好,存放到数据库端,供其他程序员来调用。 语法: create [or replace] procedure 过程名(参数1 in|out 参数类型) as|is --声明变量,游标 相当于declare beign --定义一段pl/sql程序体 end;
--给指定的员工涨工资,并且打印出涨前跟涨后的工资 --引用型变量(引用了表中某一列的类型) --记录型变量,存储了一行的数据
create or replace procedure emp_add_sal(eno in number) as psal emp.sal%type; -- psal number; pemp emp%rowtype; begin select sal into psal from emp where empno = eno; dbms_output.put_line('涨前工资: '||psal);
update emp set sal=sal+100 where empno = eno; commit; select * into pemp from emp where empno = eno; dbms_output.put_line('涨后工资: '||pemp.sal); end; --存储过程调用 emp_add_sal(7369); --调用方式2 <不推荐> call emp_add_sal(7369); --根据员工编号查询年薪 --有返回值 create or replace procedure emp_totalsal(eno in number,totalsal out number) select sal*12+nvl(comm,0) into totalsal from emp where empno = eno; --调用 declare sal number; emp_totalsal(7369,sal); dbms_output.put_line(sal); --采用第二种(不适用) call pro_emp_totalsal(7369,); --call 调用只适用于没有输出参数的存储过程


====================================== 存储函数 ======== == ===================
/* 存储过程与存储函数的区别: 存储过程能实现功能,存储函数也可以实现 语法不同:存储函数一定是有返回值。并且在函数的程序体内必须返回一个变量;变量类型跟声明返回数据类型保持一致 存储函数可以用在select语句中; */

语法: create or replace function 函数名称 (参数 in|out 参数类型) return 数据类型 as|is --定义一些变量,游标 begin return 变量; --变量类型要跟返回的数据类型保持一致 end;
--使用存储函数,查询指定员工的年薪
createorreplacefunctionfun_totalsal(enoinnumber)returnnumber as totalsalnumber; begin selectsal*12+nvl(comm,0)intototalsalfromempno=eno; returntotalsal; --调用存储函数
number;--定义变量来接收返回值 totalsal:=fun_totalsal(7369); dbms_output.put_line(totalsal); --存储函数带一个输出参数(既有返回值,又要有输出)
fun_totalsal_out(enonumber,pnameoutemp.ename%typenumber selectsal*12+nvl(comm,255)">0)intototalsalwhereempno=eno; --调用
pnamevarchar2(100); totalsal:=fun_totalsal_out(7369,pname); dbms_output.put_line(pname); --查询指定员工的信息,部门名称
fun_emp_dname(dnonumbervarchar2 as
deptname varchar2 ( 200 ); --注意声明varchar2类型长度一定要给指定
selectdnameintodeptnamefromdeptwheredeptno=dno; returndeptname; ; ename,fun_emp_dname(deptno)from10;
--查询指定部门员工信息(使用存储过程)--sys_refcursor引用游标类型
procedurepro_emplist(dnoinoutsys_refcursor) openemplistforempssys_refcursor; pempemp%rowtype; pro_emplist(20,emps); loop fetchempsintopemp; whenemps%notfound; dbms_output.put_line(pemp.ename); loop; closeemps; ;

===================================== jdbc调用oracle对象(掌握) ======= == =========================
导入jar包
PreparedStatement :
作用:1. 可以提前占位, 防SQL注入 2.提高了效率<查询时候先去数据库找缓存>
   
   
public class OracleTest { String driver = "oracle.jdbc.driver.OracleDriver"; url "jdbc:oracle:thin:@192.168.68.10:1521:orcl" username "scott" password "admin" @Test //查询所有的void testFindEmpList(){try//加载驱动 Class.forName(driver);//获取连接 Connection conn DriverManagergetConnectionurl, username password//获取 PreparedStatement 对象 PreparedStatement pst connprepareStatement("select * from emp"//执行查询 ResultSet rs pstexecuteQuery();//处理结果whilersnext()){//getObject(i)获取第几列的值,getString("列名"),getInt("列名") SystemoutprintlngetObject(1)+"--"+getString"ename"));}//释放资源 rsclosecatch(Exception e)printStackTrace}}
调用过程 无输出参数的 Connection 方法
返回值
    
    
  1. create or replace procedure emp_add_sal(eno in number)
  2. {call <procedure-name>[(<arg1>,<arg2>,...)]} */
/* * 调用存储过程 --存储过程 as psal emp.sal%type; pemp emp%rowtype; begin select sal into psal from emp where empno = eno; dbms_output.put_line('涨前工资: '||psal); update emp set sal=sal+100 where empno = eno; commit; select * into pemp from emp where empno = eno; dbms_output.put_line('涨后工资: '||pemp.sal); end; testCallProcedure); CallableStatement cst = conn.prepareCall( "{call emp_add_sal(?)}"); cstsetInt7369// TODO Auto-generated catch block}
调用过程(有输出参数)
CallableStatement:方法

   
     调用存储过程  --根据员工编号查询年薪 create or replace procedure emp_totalsal(eno in number,totalsal out number) as begin select sal*12+nvl(comm,0) into totalsal from emp where empno = eno; end; */// {call <procedure-name>[(<arg1>,...)]} testCallProcedureOutParam CallableStatement cst prepareCall"{call emp_totalsal(?,?)}"  cst.registerOutParameter(2,OracleTypesNUMBER); //获取第二个输出参数的值cst2}
调用函数

    
     --调用函数 --使用存储函数,查询指定员工的年薪 create or replace function fun_totalsal(eno in number ) return number totalsal number; return totalsal; end;    {?= call <procedure-name>[(<arg1>,...)]} */ testCallFunction"{?= call fun_totalsal(?)}"registerOutParameterOracleTypesNUMBER//获取第一个参数输出的值getInt 
调用存储过程输出参数为游标类型的:
 {call <procedure-name>[(<arg1>,...)]}
     
     
  • --调用存储过程输出参数为游标类型的 --查询指定部门员工信息(使用存储过程) --sys_refcursor 引用游标类型 create or replace procedure pro_emplist(dno in number,emplist out sys_refcursor) open emplist for select * from emp where deptno = dno; testCallProcedureOutCursor"{call pro_emplist(?,145)">20CURSORexecute ResultSet rs ((OracleCallableStatement)cst).getCursor(2);getObject}

  • -----------------------------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------------------------
    上面代码 可以简化: 用注解
      
      
    private; @Before init()throws ClassNotFoundException SQLException// 加载驱动// 获取连接@After after// 释放资源if(null!=){if}
    -----------------------------------------------------------------------------------------------------------------------------------
    -----------------------------------------------------------------------------------------------------------------------------------

    ================================================触发器======== =============================== /* 理解:好比监视器,触发器在对表中的数据进行操作(增删改),触发器就会工作。如果操作合法了,才能对数据进行改变 语法:create[orreplace]trigger after|before insert|update|delete on表名 [foreachrow]---行级触发器 declare begin end; */ --添加一条数据,自动控制台输出一句‘数据添加成功了
    triggertri_after_add after insert onperson1 declare begin '数据添加成功了'); ; insertintoperson1values(15,255)">'赵六',255)">1); commit --不能在休息(周四周六日)时间添加员工 raise_application_error(p1,p2);--错误提示框 p1:错误编码范围在-20001到-20999 p2:错误信息 */
    to_char(sysdate'day')fromdual; tri_before_add before insert onperson1 weekend50); begin selectto_char(sysdate,255)">'day')intoweekendfromdual; ifweekendin('thursday',255)">'saturday',255)">'sunday')then raise_application_error(-20002,255)">'不能在休息时间添加员工'); if; ;
    211221,sans-serif; font-size:15px; line-height:24px"> --不能给员工降薪 foreach row:行级触发器表示针对每一条数据操作都会触发, 只有用到:old:new必须声明行级触发器 tri_before_update update emp foreachrow if:old.sal>:new.sal20003,255)">'不能降薪!'); updateempsetsal=sal-100whereempno=7369; --=======触发器的应用 --目标:主键不在显示输入,自动生成
    person1(namevalues'李四1',255)">2); --创建触发器
    selectseq_person.nextvalinto:new.id;

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读