一.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. webstrom 10 注册码

    webStorm : UserName:William ===== LICENSE BEGIN ===== 45550-12042010 00001SzFN0n1bPII7FnAxnt0DDOPJA  ...

  2. asp.net core 简化模型验证 modelState.IsValid不用每一个写

    第一种:直接在执行action之前验证模型 实现 IActionFilter public class ModelStateFilter : IActionFilter { public void O ...

  3. 洛谷 P1801 黑匣子_NOI导刊2010提高(06)

    题目描述 Black Box是一种原始的数据库.它可以储存一个整数数组,还有一个特别的变量i.最开始的时候Black Box是空的.而i等于0.这个Black Box要处理一串命令. 命令只有两种: ...

  4. opencv-视频分解图片

    1.加载视频2. info信息 3. 解码,parse方法解析视频 4. imshow展示或者保存imread # 视频分解图片 # 1 load 2 info 3 parse 4 imshow im ...

  5. Redis 工具类 java 实现的redis 工具类

    最近了解了一下非关系型数据库 redis 会使用简单的命令 在自己本地电脑 使用时必须先启动服务器端 在启动客户端 redis 简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内 ...

  6. JavaScript Succinctly 读后笔记

    1.JavaScript does not have block scope  2.Scope is determined during function definintion,  not invo ...

  7. C语言之对指针概念的初步探究

    指针?什么是指针? 指针(pointer)是一个值为内存地址的变量(或数据对象). 接下来从变量的角度分析: 变量有两个属性,一个是地址,一个是值. 指针与普通变量的不同之处在于:指针变量的值是一个内 ...

  8. jquery 拖动改变div大小

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. input keyup的时候实现内容过滤

    当在文本框中输入关键字,就会搜索出包含关键字的数据 实现: 只需要一个内容过滤即可 <body> <input type="text" id="sear ...

  10. drozer与adb工具的安装与使用

    drozer:链接: https://pan.baidu.com/s/1skTJdgh 密码: wah1 adb:链接: https://pan.baidu.com/s/1gfpIkuv 密码: n8 ...