Oracle—学习笔记#day02

Oracle

Posted by DiCaprio on August 17, 2019

目录

一.视图[应用]

二.索引[应用]

三.pl/sql 基本语法[了解]

1.pl/sql  程序语法

2.常量和变量定义

3. if  分支

4.LOOP 循环语句

5. 游标 Cursor

四.存储过程[理解]

五.存储函数[理解]

六.触发器[理解]

七.Java 程序调用存储过程[应用]

1.java  连接 oracle 的 jar 

2.数据库连接字符串

3.实现存储过程的调用

过程定义

调用存储过程(包含存储过程、存储函数)


一.视图[应用]

视图就是封装了一条复杂查询的语句。
语法 1.:CREATE VIEW 视图名称 AS 子查询
范例:建立一个视图,此视图包括了 20 部门的全部员工信息
create view empvd20 as select * from emp t where t.deptno = 20
视图创建完毕就可以使用视图来查询,查询出来的都是 20 部门的员工

语法 2:CREATE OR REPLACE VIEW 视图名称 AS 子查询
如果视图已经存在我们可以使用语法 2 来创建视图,这样已有的视图会被覆盖。
create or replace view empvd20 as select * from emp t where t.deptno = 20
那么视图可以修改吗?

我们尝试着修改视图但是发现是视图所查询的表的字段值被修改了。所以我们一般不会去修改视图。
我们可以设置视图为只读

语法 3:CREATE OR REPLACE VIEW 视图名称 AS 子查询 WITH READ ONLY
create or replace view empvd20 as select * from emp t where t.deptno = 20 with readonly

二.索引[应用]

索引是用于加速数据存取的数据对象合理的使用索引可以大大降低 i/o 次数,从而
提高数据访问性能
。索引有很多种我们主要介绍常用的几种:
为什么添加了索引之后,会加快查询速度呢?
图书馆:如果杂乱地放书的话检索起来就非常困难,所以将书分类,然后再建一个箱子,箱
子里面放卡片,卡片里面可以按类查询,按书名查或者类别查,这样的话速度会快很多很多,
这个就有点像索引。索引的好处就是提高你找到书的速度,但是正是因为你建了索引,就应该有人
专门来维护索引,维护索引是要有时间精力的开销的,也就是说索引是不能乱建的,所以建索引有
个原则:如果有一个字段如果不经常查询,就不要去建索引。现在把书变成我们的表,把卡片变成
我们的索引,就知道为什么索引会快,为什么会有开销。
创建索引的语法:
创建索引:
1. 单列索引
单列索引是基于单个列所建立的索引,比如:
CREATE index 索引名 on 表名(列名)
2. 复合索引
复合索引是基于两个列或多个列的索引。在同一张表上可以有多个索引,但是
要求列的组合必须不同,比如:
Create index emp_idx1 on emp(ename,job);
Create index emp_idx1 on emp(job,ename);
范例:给 person 表的name建立索引
create index pname_index on person(name);
范例:给 person 表创建一个 name 和 gender 的索引
create index pname_gender_index on person(name, gender);
索引的使用原则:

  • 在大表上建立索引才有意义
  • 在 where子句后面或者是连接条件上的字段建立索引
  • 表中数据修改频率高时不建议建立索引

三.pl/sql 基本语法[了解]

什么是 PL/SQL?
PL/SQL(Procedure Language/SQL)
PLSQL 是 Oracle 对sql 语言的过程化扩展,指在 SQL 命令语言中增加了过程处理语句(如分支、循环等),使 SQL语言具有过程处理能力。把SQL 语言的数据操纵能力与过程语言的数据处理能力结合起来,使得 PLSQL面向过程但比过程语言简单、高效、灵活和实用。
范例 1:为职工涨工资,每人涨 10%的工资。
update emp set sal=sal*1.1
范例 2:例 2: 按职工的职称长工资,总裁涨 1000元,经理涨800 元,其他人员涨 400 元。
这样的需求我们就无法使用一条 SQL来实现,需要借助其他程序来帮助完成,也可以使用 pl/sql。

1.pl/sql  程序语法

  1. 程序语法:
  2. declare
  3. 说明部分 (变量说明,游标申明,例外说明 〕
  4. begin
  5. 语句序列 (DML 语句〕…
  6. exception
  7. 例外处理语句
  8. End;

2.常量和变量定义

  1. 在程序的声明阶段可以来定义常量和变量。
  2. 变量的基本类型就是 oracle 中的建表时字段的变量如 char, varchar2, date, number,
  3. boolean, long
  4. 定义语法:varl char(15);
  5. Psal number(9,2);
  6. 说明变量名、数据类型和长度后用分号结束说明语句。
  7. 常量定义:married constant boolean:=true
  8. 引用变量
  9. Myname emp.ename%type;
  10. 引用型变量,即my_name 的类型与emp 表中 ename 列的类型一样
  11. 在 sql中使用 into 来赋值
  12. declare
  13. emprec emp.ename%type;
  14. begin
  15. select t.ename into emprec from emp t where t.empno = 7369;
  16. dbms_output.put_line(emprec);
  17. end;
  18. 记录型变量
  19. Emprec emp%rowtype
  20. 记录变量分量的引用
  21. emp_rec.ename:='ADAMS';
  22. declare
  23. p emp%rowtype;
  24. begin
  25. select * into p from emp t where t.empno = 7369;
  26. dbms_output.put_line(p.ename || ' ' || p.sal);
  27. end;

3. if  分支

  1. 语法 1
  2. IF 条件 THEN 语句 1;
  3. 语句 2;
  4. END IF;
  5. 语法 2
  6. IF 条件 THEN 语句序列 1
  7. ELSE 语句序列 2
  8. END IF
  9. 语法 3
  10. IF 条件 THEN 语句;
  11. ELSIF 语句 THEN 语句;
  12. ELSE 语句;
  13. END IF;

4.LOOP 循环语句

  1. 语法 1
  2. WHILE total <= 25000 LOOP
  3. .. .
  4. total : = total + salary;
  5. END LOOP;
  6. 语法 2
  7. Loop
  8. EXIT [when 条件];
  9. ……
  10. End loop
  11. 语法 3
  12. FOR I IN 1 . . 3 LOOP
  13. 语句序列 ;
  14. END LOOP

5. 游标 Cursor

在写 java 程序中有集合的概念,那么在 pl/sql 中也会用到多条记录,这时候我们就要用到游标,游标可以存储查询返回的多条数据

语法:
CURSOR 游标名 [ (参数名 数据类型,参数名 数据类型,...)] IS SELECT 语句;
例如: cursor c1 is select ename from emp;
游标的使用步骤:
  打开游标: open c1; (打开游标执行查询)
  取一行游标的值:fetch c1 into pjob; (取一行到变量中)
 关闭游标: close c1;(关闭游标释放资源)
 游标的结束方式 exit when c1%notfound
 注意: 上面的 pjob 必须与 emp表中的 job 列类型一致:
定义:pjob emp.empjob%type;

四.存储过程[理解]

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的 SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。

  1. 创建存储过程语法:
  2. create [or replace] PROCEDURE 过程名[( 参数名 in/out 数据类型)]
  3. AS
  4. begin
  5. PLSQL 子程序体;
  6. End;
  7. 或者
  8. create [or replace] PROCEDURE 过程名[( 参数名 in/out 数据类型)]
  9. is
  10. begin
  11. PLSQL 子程序体;
  12. End 过程名;

五.存储函数[理解]

  1. create or replace function 函数名(Name in type, Name in type, ...) return 数据类型 is
  2. 结果变量 数据类型;
  3. begin
  4. return( 结果变量);
  5. end 函数名;

存储过程和存储函数的区别
一般来讲,过程和函数的区别在于函数可以有一个返回值;而过程没有返回值。
但过程和函数都可以通过 out 指定一个或多个输出参数。我们可以利用out 参数,在过程和函数中实现返回多个值。

六.触发器[理解]

数据库触发器是一个与表相关联的、存储的 PL/SQL 程序。每当一个特定的数据操作语句(Insert,update,delete)在指定的表上发出时,Oracle 自动地执行触发器中定义的语句序列。

触发器可用于
  数据确认
  实施复杂的安全性检查
  做审计,跟踪表上所做的数据操作等
  数据的备份和同步

  1. 触发器的类型
  2. 语句级触发器 :在指定的操作语句操作之前或之后执行一次,不管这条语句影响
  3. 了多少行 。
  4. 行级触发器(FOR EACH ROW) :触发语句作用的每一条记录都被触发。在行级触
  5. 发器中使用 old 和 new伪记录变量, 识别值的状态。
  6. 语法:
  7. CREATE [or REPLACE] TRIGGER 触发器名
  8. {BEFORE | AFTER}
  9. {DELETE | INSERT | UPDATE [OF 列名]}
  10. ON 表名
  11. [FOR EACH ROW [WHEN( 条件) ] ]
  12. begin
  13. PLSQL 块
  14. End 触发器名

七.Java 程序调用存储过程[应用]

1.java  连接 oracle 的 jar 

ojdbc14.jar

2.数据库连接字符串

  1. String driver="oracle.jdbc.OracleDriver";
  2. String url="jdbc:oracle:thin:@192.168.56.10:1521:orcl";
  3. String username="scott";
  4. String password="tiger";

测试代码:

3.实现存储过程的调用

过程定义

  1. -- 统计年薪的过程
  2. create or replace procedure proc_countyearsal(eno in number,esal
  3. out number)
  4. as
  5. begin
  6. select sal*12+nvl(comm,0) into esal from emp where empno=eno;
  7. end;
  8. -- 调用
  9. declare
  10. esal number;
  11. begin
  12. proc_countyearsal(7839,esal);
  13. dbms_output.put_line(esal);
  14. end;

调用存储过程(包含存储过程、存储函数)

  1. @Test
  2. public void testProcedure01(){
  3. String driver="oracle.jdbc.OracleDriver";
  4. String url="jdbc:oracle:thin:@192.168.56.10:1521:orcl";
  5. String username="scott";
  6. String password="tiger";
  7. try {
  8. Class.forName(driver);
  9. Connection con = DriverManager.getConnection(url,
  10. username, password);
  11. CallableStatement callSt = con.prepareCall("{call
  12. proc_countyearsal(?,?)}");
  13. callSt.setInt(1, 7839);
  14. callSt.registerOutParameter(2, OracleTypes.NUMBER);
  15. callSt.execute();
  16. System.out.println(callSt.getObject(2));
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }
  20. }