一.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. P4841 城市规划 FFT+生成函数

    \(\color{#0066ff}{ 题目描述 }\) 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使 ...

  2. luogu2522 [HAOI2011]Problem b

    luogu2522[HAOI2011]Problem b 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公 ...

  3. 数据结构java学习(三)循环队列

    @TOC 和栈一样,队列也是表,但是使用队列的特点是先进先出. 队列模型 \(\color{black}{队列的基本操作是入队,它是在表的末端插入一个元素,和出队,它是删除在表开头的一个元素}\) g ...

  4. 圆环进度css

    看效果先:http://sandbox.runjs.cn/show/b6bmksvn 参考: jquery圆环百分比进度条制作 CSS clip:rect矩形剪裁功能及一些应用介绍 CSS clip: ...

  5. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_类型转换

    1. C# 不要求任何特殊语法即可将一个对象转换为它的任何基类型,因为向基类型的转换被认为是一种安全的隐式转换: 2. 然而,将对象转换为它的某个派生类型时,C#要求开发人员只能进行显示转换,因为这样 ...

  6. nginx编译报错

    [root@vm_0_2_centos nginx-1.12.2]# ./configure --prefix=/application/nginx-1.12.2 --user=www --group ...

  7. 1.centos7 安装zookeeper

    1.安装jdk 1)查找jdk包: yum search java|grep jdk 2)安装: yum install -y java-1.8.0-openjdk.x86_64 2. 安装ZooKe ...

  8. vue入门----------路由配置

    在使用脚手架搭建好项目后要配置路由 1.首先要安装vue-router,你可以在项目的package.json文件中的dependencies项目中添加"vue-route": & ...

  9. 信息领域热词分析系统--python切词

    利用python将标题切割成词语 import jieba #读取文件 f=open(r"F:\大数据\大作业\爬取到的数据\data1_xinxi.txt",'r') s=f.r ...

  10. 搭建并行开发环境MPICH2

    平台信息 Description: CentOS Linux release 7.6.1810 (Core) 注意事项 安装BLAS之前需要: 安装 GCC/GFortran 环境 安装步骤 下载 m ...