Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器

一.pl/sql(Procedure Language/SQL)编程语言

1.概念

PL/SQL是Oracle数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编程语言的特点,所以PL/SQL把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算。PL/SQL 只有 Oracle 数据库有。 MySQL 目前不支持 PL/SQL 的。

2.变量和常量

声明普通变量:
     v_name varchar2(30) := ‘tom‘;  (:=为赋值符号;=为比较符号,相当于java中的==);

声明引用型变量:
     v_sal emp.sal%type := 100;    声明的v_sal变量与emp表中sal字段的类型一致;

声明记录型变量:
     v_row emp%rowtype; 记录型变量相当于java中的resultset,用来存储整张表中的数据;

声明常量:
     v_gender constant number(1) number(1) := 1;

3.分支语句

语法一:if ---then---end if;

语法二:if ---then---else---end if;

语法三:if ---then---elsif---then----else----end if;

举例:

--年龄小于18,显示未成年人,18-60,显示成年人,60以上显示老年人

declare
     v_age number(8) :=#

begin
     if v_age < 18 then
         dbms_output.put_line(‘未成年人‘);
     elsif v_age >= 18 and v_age <= 60 then
         dbms_output.put_line(‘成年人‘);
     else
         dbms_output.put_line(‘老年人‘);
     end if;

end;

4.循环语句

语法一:loop---exit when----end loop;

举例:

--输出1--100的数

declare
  v_num number(8) := 1;

begin
  loop
   exit when v_num > 100;
   dbms_output.put_line(v_num);
   v_num := v_num + 1;
  end loop;

end;

语法二:while---loop----end loop;

declare
  v_num number(8) := 1;

begin
  while v_num <= 100 loop
   dbms_output.put_line(v_num);
   v_num := v_num + 1;
  end loop;

end;

语法三:for---in 起始值..终止值---loop---end loop;

declare
  v_num number(8) := 1;

begin
  for v_num in 1 .. 100 loop
   dbms_output.put_line(v_num);
  end loop;

end;

5.游标(cursor)

作用:用来接收多条数据结果,相当于java中的ResultSet

语法:cursor 游标名称 is sql 查询语句;

使用:
     open 游标名称
     loop
         fetch 游标名称 into 记录型变理
         exit when 游标名称%notfound;
             逻辑处理
     end loop;
     close 游标名称;

举例:

--打印emp表的所有信息

DECLARE
  CURSOR c_emp IS SELECT * FROM emp;
  v_row emp%ROWTYPE;

BEGIN
  OPEN c_emp;
  LOOP
    FETCH c_emp INTO v_row;
          EXIT WHEN c_emp%NOTFOUND;
          dbms_output.put_line(v_row.ename||‘--‘||v_row.job);
   END LOOP;
   CLOSE c_emp;

END;

--带参数的游标

DECLARE
   CURSOR c_emp(v_no1 NUMBER, v_no2 NUMBER) IS SELECT * FROM emp WHERE deptno = v_no1 OR deptno = v_no2;
   v_row emp%ROWTYPE;

BEGIN
  OPEN c_emp(10,20);--传入部门编号deptno
  LOOP
   FETCH c_emp INTO v_row;
   EXIT WHEN c_emp%NOTFOUND;
   dbms_output.put_line(v_row.ename||‘==‘||v_row.job);
  END LOOP;
  CLOSE c_emp;

END;

6.异常

exception---when----then

--预定义异常

DECLARE
  v_num NUMBER(3);
  BEGIN
   v_num := 10000;
   EXCEPTION
    WHEN value_error THEN
     v_num := 999;
     dbms_output.put_line(v_num);
  END;

--自定义异常
   DECLARE
   V_AGE NUMBER(8) := &NUM;
   EXC_AGE EXCEPTION; --声明异常
  BEGIN
   IF V_AGE > 150 THEN
    RAISE EXC_AGE;
   END IF;
  EXCEPTION
   WHEN EXC_AGE THEN
    RAISE_APPLICATION_ERROR(-20001, ‘illegal age‘);
  END;

二.存储过程

概念:一段被命名的plsql,预编译到了数据库中

语法:
     create or replace procedure 存储过程名字(参数1 [in]/out 数据类型)
         as | is
         begin

end;

例子1:
  --存储过程,打印指定员工的年薪
  create or replace procedure pro_emp_sal(v_no number) is
  v_sal number(8, 2);

begin
  select sal * 12 + nvl(comm, 0) into v_sal from emp where empno = v_no;
  dbms_output.put_line(v_sal);

end;

--方法一调用存储过程
  call pro_emp_sal(7788);

--方法二调用存储过程

begin
  pro_emp_sal(7788);

end;

例子2:带out参数的存储过程

CREATE OR REPLACE PROCEDURE pro_emp_sal2(v_no NUMBER, v_yearsal OUT NUMBER) IS

BEGIN
  SELECT sal*12 + NVL(comm,0) INTO v_yearsal FROM emp WHERE empno = v_no;

END;

--只能使用方式二调用

DECLARE
  v_sal NUMBER(8,2);
  BEGIN
   pro_emp_sal2(7788,v_sal);
   dbms_output.put_line(v_sal);
  END;

三.存储函数

--存储函数

CREATE OR REPLACE FUNCTION fun_emp_sal(v_no NUMBER)

RETURN NUMBER

IS

v_sal NUMBER(8,2);

BEGIN
  SELECT sal*12+NVL(comm,0) INTO v_sal FROM emp WHERE empno = v_no;
  RETURN v_sal;
  END;
  --使用存储函数
  BEGIN
   dbms_output.put_line(fun_emp_sal(7788));
   END;

注:存储过程和存储函数的区别

1、语法不同

2、使用场景:一般存储函数多被存储过程使用,存储过程一般使用在项目和项目之间的数据交互

3、存储函数可以直接在sql中使用,而存储过程不能

select ename,sal,func_emp_sal(empno)  from emp;

四.使用jdbc调用存储过程和存储函数

1.BaseDao用于加载驱动和获取连接

2.ProcedureDao用于调用存储过程

3.TestDao用于测试

举例:

1.BaseDao用于加载驱动和获取连接

public class BaseDao {
      //加载驱动
     static{
         try {
             Class.forName("oracle.jdbc.OracleDriver");
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         }
     }
    
     //获取连接
     public static Connection getConn() throws SQLException{
         String url="jdbc:oracle:thin:@192.168.92.8:1521:orcl";
         String user="qin";
         String password="qin";
         return DriverManager.getConnection(url, user, password);
     }
    
     public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
         if(rs!=null){
             try {
                 rs.close();
             } catch (SQLException e) {
                 e.printStackTrace();
             }
         }
         if(stmt!=null){
             try {
                 stmt.close();
             } catch (SQLException e) {
                 e.printStackTrace();
             }
         }
         if(conn!=null){
             try {
                 conn.close();
             } catch (SQLException e) {
                 e.printStackTrace();
             }
         }
     }

}

2.ProcedureDao用于调用存储过程

public class ProcedureDao {
     public static Long  getSal(Long v_no){
         Connection conn = null;
         CallableStatement stmt=null;
         Long yearsal=0l;

try {
             conn=BaseDao.getConn();
             stmt = conn.prepareCall("call pro_emp_sal2(?,?)");//调用存储过程
             stmt.setLong(1, v_no);
             stmt.registerOutParameter(2, OracleTypes.NUMBER);    //指定参数的数据类型
             stmt.execute();
             yearsal = stmt.getLong(2);
         } catch (SQLException e) {
             e.printStackTrace();
         }
         return yearsal;
     }

}

3.TestDao用于测试

public class TestDao {
     public static void main(String[] args) {
         CursorDao.getEmp(10l);
     }

}

五.触发器

1.--创建添加数据引发操作的触发器

CREATE OR REPLACE TRIGGER tri_add_emp

AFTER

INSERT ON emp

BEGIN
  dbms_output.put_line(‘增加了一条数据‘);

END;

--增加一条数据,看是否会触发

INSERT INTO emp(empno,ename,deptno) VALUES(1,‘tom‘,10);

2.--系统时间引发的触发器

CREATE OR REPLACE TRIGGER tri_emp

BEFORE

DELETE OR UPDATE OR INSERT

ON emp

FOR EACH ROW

DECLARE
  v_dateStr VARCHAR2(20);

BEGIN
  SELECT to_char(SYSDATE,‘yyyy-mm-dd‘) INTO v_dateStr FROM dual;
  IF v_dateStr = ‘2017-09-20‘ THEN
   raise_application_error(-20002,‘今天系统维护‘);
   END IF;
  END;
 
  --测试是否能引发触发器
  INSERT INTO emp(empno,ename,deptno) VALUES (3,‘jerry‘,10);

六.误删除数据恢复语句

create table tableName_bak

as

select * from tableName as of TIMESTAMP to_timestamp(‘20081126 103435‘,‘yyyymmdd hh24miss‘);

时间: 2025-01-20 01:04:47

Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器的相关文章

Oracle实践--PL/SQL基础之游标

PL/SQL基础入门之游标 PL/SQL:过程语言(Procedure  Language)和结构化语言(Structured Query Language)结合而成的编程语言,是对SQL的扩展,支持多种数据类型,如大对象和集合类型,可使用条件和循环等控制语句,可创建存储过程,程序包和触发器等,给sql语句的执行添加程序逻辑,与Oracle服务器和Oracle工具紧密集成,具有可移植性,灵活性和安全性. ----------------------------------------------

Oracle数据库之PL/SQL程序设计简介

有利于客户/服务器环境应用的运行 对于客户/服务器环境来说,真正的瓶颈是网络上.无论网络多快,只要客户端与服务器进行大量的数据交换,应用运行的效率自然就回受到影响.如果使用PL/SQL进行编程,将这种具有大量数据处理的应用放在服务器执行,自然就省去了数据在网上的传输时间. 适合于客户环境 PL/SQL由于分为数据库PL/SQL部分和工具PL/SQL.对于客户端来说,PL/SQL可以嵌套到相应的工具中,客户端程序可以执行本地包含PL/SQL部分,也可以向服务发SQL命令或激活服务器端的PL/SQL

每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQL程序设计终极指南>志在打造PL/SQL领域最为系统.全面.实战.权威的著作,通过一系列非常突出的优势在大量的同类书中脱颖而出,成为该领域的标准读物. PL/SQL本身涉及的知识点浩瀚.庞杂,初学者根本无法依靠自身能力理清头绪,学习成本极高.本书对知识点进行了体系化的梳理,化繁杂为有序,突出重点,直指核

[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) 得到了大家的强力支持与建议,万分感谢.接下来介绍下一篇:oracle pl/sql异常处理部分,还望大家一定

【转】[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼、百战不殆)

[推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/SQL编程之八:把触发器说透 ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) 得到了大家的强力支持与建议,万分感谢.接下来介绍下一篇:oracle pl/sql异常处理部分,还望大家一定要支持与推荐呀~! 本篇主要内容如下: 5.1 异常处理概念 5.1.1 预定义的异常

Oracle数据库之PL/SQL异常处理

Oracle数据库之PL/SQL异常处理 异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的. PL/SQL程序设计过程中,即使是写得最好的程序也可能会遇到错误或未预料到的事件.一个健壮的程序都应该能够正确处理各种异常情况,并尽可能从中恢复. 1. 异常处理 异常处理是用来处理正常执行过程中未预料的事件.PL/SQL程序块一旦产生异常而没有指出如何处理时,程序就会自动终止整个程序运行. PL/SQL编程过程中,有三种类型的异常: 1.预定义异常 对这种异常情况的处

Oracle 11g 的PL/SQL函数结果缓存

模仿Oracle性能诊断艺术中的例子做了两个试验,书上说如果不用RELIES_ON,则函数依赖的对象发生的变更操作就不会导致结果缓存的失效操作(result_cache RELIES_ON(test1,test2)),试验证明不对,函数f1()并没有使用RELIES_ON,但表上的变化影响到了函数. C:\Documents and Settings\guogang>sqlplus gg_test/[email protected]_gg SQL*Plus: Release 10.2.0.1.0

Oracle 客户端安装 + pl/sql工具安装配置

Oracle 客户端安装 +  pl/sql工具安装配置 下载oracle客户端,并在本地安装. 11g下载地址为: http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 10g下载地址为: http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 根据自己机器或者oracle服

《oracle每日一练》免安装Oracle客户端使用PL/SQL

免安装Oracle客户端使用PL/SQL Oracle客户端挺招人烦的,部署连接它的应用通常需要先安装它的客户端,安装程序要求在目标机器上写注册表,假设你没有洁癖的话,你仍可能被下面的事情绊住:当你的机器上的其他程序依赖于x64的Oracle的程序,并且它们很有可能根本不是你写的,因此你还不敢随便乱动服务器,但是你可能需要一个PL/SQL用来在相同的环境下执行查询,这个时候你还是需要一个免安装的办法来处理这个问题. 1.下载Oracle Instant Client (32-bit) 因为我的P