一.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');

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

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

    PL/SQL程序设计简介 一.什么是PL/SQL? PL/SQL是 Procedure Language & Structured Query Language 的缩写. ORACLE的SQL ...

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

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

  3. Oracle数据库之PL/SQL包

    Oracle数据库之PL/SQL包 1. 简介 包(PACKAGE)是一种数据对象,它是一组相关过程.函数.变量.常量和游标等PL/SQL程序设计元素的组合,作为一个完整的单元存储在数据库中,用名称来 ...

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

    Oracle数据库之PL/SQL异常处理 异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的. PL/SQL程序设计过程中,即使是写得最好的程序也可能会遇到错误或未预料 ...

  5. Oracle数据库之PL/SQL流程控制语句

    Oracle数据库之PL/SQL流程控制语句 在任何计算机编程语言(如C,Java,C#等)都有各种流程控制语句,同样,在PL/SQL中也存在这样的流程控制结构. 几种常见的流程控制结构: 一.条件结 ...

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

    原文:[推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不殆) [推荐]ORACLE PL/SQL编程之五: 异常错误处理(知已知彼.百战不殆) 继上三篇:ORACLE PL/S ...

  7. oracle系列(四)PL/SQL

    过程,函数,触发器是PL/SQL编写的,存储在oracle中的.PL/SQL是非常强大的数据库过程语言. PL/SQL优点:性能,模块化,网络传输量,安全性缺点:移植性不好 简单分类:块:过程,函数, ...

  8. oracle数据库之PL/SQL 块结构和组成元素

    一.PL/SQL 块 (一)PL/SQL 程序由三个块组成,即声明部分.执行部分.异常处理部分 PL/SQL 块的结构如下: 1.DECLARE /* 声明部分: 在此声明 PL/SQL 用到的变量, ...

  9. Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器

    ---视图 ---视图的概念:视图就是提供一个查询的窗口,来操作数据库中的数据,不存储数据,数据在表中. ---一个由查询语句定义的虚拟表. ---查询语句创建表 create table emp a ...

随机推荐

  1. Python中的Numpy包

    通过本次学习你可以掌握Numpy Numpy介绍(获取地址)更多Numpy函数 numpy的主要对象是同质多维数组.也就是在一个元素(通常是数字)表中,元素的类型都是相同的. numpy的数组类被成为 ...

  2. springcloud系列五 feign远程调用服务

    一:Feign简介 Feign 是一种声明式.模板化的 HTTP 客户端,在 Spring Cloud 中使用 Feign,可以做到使用 HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完 ...

  3. js 点击图片放大,再点击缩小还原

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. js-带操作的赋值表达式

    带操作的赋值表达式为: a op= b 这里op代表一个运算符,这个表达式等价于: a = a op b 这里需要特别注意:在第一个表达式中,表达式a计算了一次,而在第二个表达式中,表达式a计算了两次 ...

  5. poj3274 找平衡数列(哈希加一点数学思维)

    题目传送门 题目大意:有n只牛,每只牛有k个属性,接下来n个数字,每个数字的二进制位上的1和0分别表示某种属性的有或者无,然后一个特殊数列就是,一个区间内所有牛的各种属性的总和相等(有e种1属性  e ...

  6. 经典SQL行列转换

    -- http://www.programbbs.com/doc/4885.htm /* 标题:普通行列转换(version 2.0) 说明:普通行列转换(version 1.0)仅针对sql ser ...

  7. NorFlash基础

    1. Nor Flash 简介 Nor Flash 闪速存储器具有可靠性高.随机读取速度快的优势,在擦出和编程操作较少而直接执行代码的场合,尤其是纯代码存储的应用中广泛使用. 2. Nor Flash ...

  8. Zero Sum Subarray

    Given an integer array, find a subarray where the sum of numbers is zero. Your code should return th ...

  9. my.资料__烹饪炼药

    ZC: 新区的时候,烹饪炼药 也不是 等级越高越好:等级越高需要的人可能少,价格高 但是买的人少:大家都在那个等级 很容易堵车 没有摊位... 刚开始 大家都穷 可能等级稍低的 反而好卖... ZC: ...

  10. js学习笔记 -- 函数

    js函数有类似javaMethod用法 Math.max.apply( Math.max.call( Array map,reduce,filter,sort , , , , , , , , ]; v ...