oracle入门(二)
### 一,视图
```
1. 什么是视图
视图是一张虚表, 可以把视图看成表使用(增删改查),视图中没有数据,所有的数据都在基本表中(tables)
封装了一个复杂的DQL
操作视图就是操作table
视图一般不作为修改数据使用, 只用作查询
2. 语法
create [or replace] view 视图名 as DQL;
3. 栗子
create or replace view emp_view as select * from emp;
select * from emp_view;
select * from emp;
insert into emp_view(empno ,ename) values(1000, 'rose');
-- 作用一 : 可以屏蔽敏感列
create or replace view employee
as select empno ,ename ,job ,mgr, hiredate ,deptno from emp;
select * from emp_view;
-- 作用二:可以定义只读的视图
create or replace view employee
as select empno ,ename ,job ,mgr, hiredate ,deptno from emp with read only;
-- 错误:virtual column not allowed here
insert into employee(empno ,ename) values(1001, 'rose');
```
### 二、索引
```
1. 索引的目的
提高检索效率
前提:百万条记录以上, 不经常的修改列 , 经常查询的列
2. 语法: create index 索引 on 表(列1,列2)
3. 测试效率
准备表,数据
create table a(
b number primary key ,
c varchar2(200)
)
create sequence a_seq;
select sys_guid() from dual;
declare
begin
for i in 1..1000000 loop
insert into a values(a_seq.nextval ,sys_guid() );
end loop;
end;
添加索引前查询
select * from a where c = '1407AB1D7E26496797E63E2C7DA76DB9'; -- 0.546
添加索引
create index a_index on a(c);
添加索引后查询
select * from a where c = '9C4CD7D2251348E4B02756BEE7558C46'; -- 0.063
4. 复合索引的触发条件(了解) address age
where address = '' and age = '' 触发索引
where address = '' or age = '' 不能触发索引
where address = '' 触发索引
where age = '' 不能触发索引
```
### 三、plsql的基本语句(过程化语言)
```
1. plsql P: procedure 过程化
2. 过程化语言的基本结构
declare
-- 声明语句
begin
--- 过程化语言
[exception]
end;
3. 声明变量
declare
-- 声明普通变量
i number;
-- 声明变量且赋值
j number default 200;
-- 引用类型:引用某表.某列的类型
pname emp.ename%type;
pjob emp.job%type;
-- 记录类型:引用表的一行的列
emp_row emp%rowtype;
begin
-- 赋值语句
i := 100;
-- 打印
dbms_output.put_line(i);
-- || 连接符
dbms_output.put_line('j = ' || j);
--赋值语句: select 查询的列 into 变量;
select ename, job into pname,pjob from emp where empno = 7788;
dbms_output.put_line(pname || '::' ||pjob);
select * into emp_row from emp where empno = 7788;
dbms_output.put_line(emp_row.ename || '::' ||emp_row.job || emp_row.hiredate);
end;
4 . if语句
格式
if 条件 then
SQL语句;
end if;
if 条件 then
SQL语句;
else
sql语句;
end if;
if 条件 then
SQL语句;
elsif 条件 then
sql语句;
....
else
sql语句;
end if;
-- 输入一个整数,如果大于0,打印正数,如果小于,打印负数,否则打印零
declare
i number;
begin
i := &请输入;
if i > 0 then
dbms_output.put_line('正数');
elsif i<0 then
dbms_output.put_line('负数');
else
dbms_output.put_line('零');
end if;
end;
5. 循环
1) for 循环
/*
for 变量 in 集合|游标 loop
end loop;
*/-- 打印1-10所有的整数
declare
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
2) 语法
/*
loop
循环体;
退出条件; exit when 条件;
end loop;
*/
-- 打印1-10所有的整数
declare
i number default 1;
begin
loop
dbms_output.put_line(i);
exit when i = 10;
i := i + 1;
end loop;
end;
3) 语法
/*
while 条件 loop
循环体;
end loop;
*/
-- 打印1-10所有的整数
declare
i number default 1;
begin
while i <= 10 loop
dbms_output.put_line(i);
i := i + 1;
end loop;
end;
```
### 四、游标
```
1. 什么是游标(主要使用在存储过程中)
就是一个集合
主要作用处理返回多行记录的问题
2. 声明游标
cursor 游标名 is DQL;
3. 遍历游标
1) 打开游标
open 游标名
2) 提取单行的记录
fetch 游标名 into 变量中;
3) 使用循环
结束语句: exit when 游标名%notfound;
4) 关闭游标
close 游标名;
4. 栗子
-- 使用游标在控制台打印20号部门的员工信息
declare
cursor cur is select * from emp where deptno = 20;
erow emp%rowtype;
begin
open cur;
loop
fetch cur into erow;
exit when cur%notfound; -- 判断是否提取到了记录
dbms_output.put_line(erow.empno || erow.ename ||erow.job);
end loop;
close cur;
end;
select * from emp where deptno = 20;
-- 给20号部门的所有员工涨工资
declare
cursor cur is select empno from emp where deptno = 20;
begin
-- for 特点:自动打开和关闭游标
-- a 是一个记录变量, 存放游标一行的记录
for a in cur loop
update emp set sal = sal +1 where empno = a.empno;
end loop;
commit;
end;
```
### 五、存储过程(重点)
```
1. 什么是存储过程
封装了一组sql语句, 提前编译,存储在服务端,
一般是由dba定义
2. 存储过程的使用场景
网上买了一件商品:商品表(update),订单表(insert), 余额表(update),销量表(update),物流表(insert)
日志表(insert)
3. 语法
create or replace procedure 过程名(参数1 in | out 数据类型, 参数2 in | out 数据类型,...)
as|is
-- 声明语句
begin
-- plsql
end;
4 .栗子 -- 只有输入参数
给某员工涨工资, 在控制台上打印涨前的工资和涨后的工资
create or replace procedure updateSal(eno in number, psal in number)
is
oldsal emp.sal%type;
newsal emp.sal%type;
begin
select sal into oldsal from emp where empno = eno;
dbms_output.put_line('涨前的工资:'||oldsal );
update emp set sal = sal + psal where empno = eno;
commit;
select sal into newsal from emp where empno = eno;
dbms_output.put_line('涨后的工资:'||newsal );
end;
-- 访问存储过程
call updateSal(7788,5);
5. 栗子 有输入有输出参数的存储过程
-- 获取某员工的年薪
create or replace procedure getYearSalByEno(eno in number, yearsal out number)
as
begin
select sal * 12 + nvl(comm , 0) into yearsal from emp where empno = eno;
end;
-- 访问存储过程
declare
yearsal number;
begin
getYearSalByEno(7902, yearsal);
dbms_output.put_line('年薪:' || yearsal);
end;
6. 栗子: 输出参数为游标类型
-- 获取某部门的所有员工信息
-- cursor :静态的游标
-- sys_refcursor:动态的游标,动态的指定sql语句
create or replace procedure getEmpsByDeptno(dno in number ,emps out sys_refcursor)
as
begin
-- 动态游标赋值sql语句
open emps for
select * from emp where deptno = dno;
end;
-- 访问带有输出参数为游标的存储过程
declare
emps sys_refcursor;
erow emp%rowtype;
begin
getEmpsByDeptno(20 ,emps);
-- 遍历游标
loop
fetch emps into erow;
exit when emps%notfound;
dbms_output.put_line(erow.empno ||erow.ename);
end loop;
close emps;
end;
```
### 六、存储函数(重点)
```
1. 什么是存储过程
封装了一组sql语句, 提前编译,存储在服务端
一般是由dba定义
一般在存储函数中没有输出参数
2. 与存储过程的区别
存储函数必须有一个返回值
存储函数可以使用select语句访问
3. 语法
create or replace function 函数名(参数1 in | out 数据类型, 参数2 in | out 数据类型,...)
retrun 类型
as|is
begin
return 值;
end;
4. 栗子: 获取某员工的年薪
create or replace function getYearSalByEnoFun(eno in number) return number
as
yearsal number;
begin
select sal * 12 + nvl(comm , 0) into yearsal from emp where empno = eno;
return yearsal;
end;
-- 访问存储函数
declare
yearsal number;
begin
yearsal := getYearSalByEnoFun(7902);
dbms_output.put_line(yearsal);
end;
5. 可以用在select语句中
select getYearSalByEnoFun(7902) from dual;
select length('abc') from dual;
```
### 七,触发器
```
1. 什么是触发器
监听器: 监听表的数据是否发生改变(insert ,update ,delete)
2. 语法
create or replace trigger 触发器名称
before | after
insert |update |delete
on 表
触发器的级别
表级触发器:默认的
行级触发器:更新一条记录,执行一次,
如果使用old,new ,必须使用行级触发器
for each row
declare
begin
end;
3. 栗子1
添加一条记录,在控制台打印 ’添加了一条记录‘
create or replace trigger insertEmp
after
insert
on emp
declare
begin
dbms_output.put_line('添加了一条记录');
end;
insert into emp(empno ,ename) values(1002 ,'mike');
4. 栗子2:不能给员工降薪
create or replace trigger notUpdateEmpLowerSal
before
update
on emp
for each row
declare
begin
if :old.sal > :new.sal then
-- 提示:不能降薪
--dbms_output.put_line('不能降薪');
-- raise_application_error(p1,p2)
-- p1 : 错误的编号(-20001 ~~~ -20999)
-- p2: 错误的提示信息
raise_application_error(-20001, '不能降薪');
end if;
end;
update emp set sal = sal + 1 where empno = 7788;
```

### 八,JDBC调用存储过程和存储函数
```
package com.jjy;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import oracle.jdbc.driver.OracleCallableStatement;
import oracle.jdbc.driver.OracleTypes;
public class JDBCTest {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@192.168.***.***:1521:orcl";
String username = "scott";
String password = "tiger";
Connection conn;
PreparedStatement pst;
CallableStatement cst;
ResultSet rs;
/**
* 在执行test方法之前执行before
*/
/**
* 初始化信息
* @throws Exception
*/
@Before
public void init() throws Exception{
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
}
/**
* 访问存储过程
* create or replace procedure getYearSalByEno(eno in number, yearsal out number)
* {call <procedure-name>[(<arg1>,<arg2>, ...)]}
*/
@Test
public void testProcedure()throws Exception{
//声明sql语句
String sql = "{call getYearSalByEno(?,?)}";
//创建statement对象
cst = conn.prepareCall(sql);
//设置占位符
cst.setInt(1, 7902);
//设置输出参数的类型
cst.registerOutParameter(2, OracleTypes.NUMBER);
//执行sql语句
cst.executeUpdate();
//获取结果
int yearsal = cst.getInt(2);
System.out.println("年薪:" + yearsal);
}
/**
* 访问存储过程
* create or replace procedure getEmpsByDeptno(dno in number ,emps out sys_refcursor)
* {call <procedure-name>[(<arg1>,<arg2>, ...)]}
*/
@Test
public void testProcedureOutCursor() throws Exception{
//声明sql语句
String sql = "{call getEmpsByDeptno(?,?)}";
//创建statement对象
cst = conn.prepareCall(sql);
//设置占位符
cst.setInt(1, 20);
//设置输出参数的类型
cst.registerOutParameter(2, OracleTypes.CURSOR);
//执行sql语句
cst.executeUpdate();
// //获取结果
//OracleCallableStatement ocst = (OracleCallableStatement) cst;
// rs = (ResultSet) cst.getObject(2);
// while(rs.next()){
// System.out.println(rs.getInt("empno") + rs.getString("ename"));
// }
}
/**
* 访问存储函数
* {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
* create or replace function getYearSalByEnoFun(eno in number) return number
*/
@Test
public void testFunction()throws Exception{
//声明sql语句
String sql = "{?= call getYearSalByEnoFun(?)}";
//创建statement对象
cst = conn.prepareCall(sql);
//设置占位符
cst.registerOutParameter(1, OracleTypes.NUMBER);
cst.setInt(2, 7902);
//执行sql语句
cst.executeUpdate();
//获取结果
int yearsal = cst.getInt(1);
System.out.println("年薪:" + yearsal);
}
/**
* 查询员工中的记录
* @throws Exception
*/
@Test
public void test()throws Exception {
String sql = "select * from emp";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("empno") + rs.getString("ename"));
}
}
/**
* 关闭资源
*/
@After
public void close()throws Exception{
if(rs != null){
rs.close();
}
if(pst != null){
pst.close();
}
if(cst != null){
cst.close();
}
if(conn != null){
conn.close();
}
}
}
```
oracle入门(二)的更多相关文章
- 【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
前言 NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能.这其中最流行的无非就是MINA和Netty了,MINA目前的主要版本是MINA2.而Netty的主要版本是Netty3和Netty ...
- Swift语法基础入门二(数组, 字典, 字符串)
Swift语法基础入门二(数组, 字典, 字符串) 数组(有序数据的集) *格式 : [] / Int / Array() let 不可变数组 var 可变数组 注意: 不需要改变集合的时候创建不可变 ...
- Thinkphp入门 二 —空操作、空模块、模块分组、前置操作、后置操作、跨模块调用(46)
原文:Thinkphp入门 二 -空操作.空模块.模块分组.前置操作.后置操作.跨模块调用(46) [空操作处理] 看下列图: 实际情况:我们的User控制器没有hello()这个方法 一个对象去访问 ...
- DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表
原文:DevExpress XtraReports 入门二 创建 data-aware(数据感知) 报表 本文只是为了帮助初次接触或是需要DevExpress XtraReports报表的人群使用的, ...
- Oracle入门4-REF Cursor
Oracle入门4-REF Cursor 转自:http://blog.sina.com.cn/s/blog_55dbebb00100gxsc.html 自:http://blog.csdn.net/ ...
- css入门二-常用样式
css入门二-常用样式总结 基本标签样式 背景色background-color 高度height; 宽度width; 边框对齐以及详细设定举例 width/*宽度*/: 80%; height/*高 ...
- 微服务(入门二):netcore通过consul注册服务
基础准备 1.创建asp.net core Web 应用程序选择Api 2.appsettings.json 配置consul服务器地址,以及本机ip和端口号信息 { "Logging&qu ...
- IM开发者的零基础通信技术入门(二):通信交换技术的百年发展史(下)
1.系列文章引言 1.1 适合谁来阅读? 本系列文章尽量使用最浅显易懂的文字.图片来组织内容,力求通信技术零基础的人群也能看懂.但个人建议,至少稍微了解过网络通信方面的知识后再看,会更有收获.如果您大 ...
- 脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?
1.引言 本文接上篇<脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手>,继续脑残式的网络编程知识学习 ^_^. 套接字socket是大多数程序员都非常熟悉的概念,它是计算机 ...
随机推荐
- 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)
问题描述: 有时候使用 apt-get 终端提示这样的错误信息: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E: 无法锁定管理目录(/var/lib/ ...
- jQuery的安装
一.jQuery的安装 下载 jQuery 有两个版本的 jQuery 可供下载: Production version - 用于实际的网站中,已被精简和压缩. Development version ...
- Python startswith()函数 与 endswith函数
函数:startswith() 作用:判断字符串是否以指定字符或子字符串开头一.函数说明语法:string.startswith(str, beg=0,end=len(string)) 或 ...
- 使用Virtual Audio Cable软件实现电脑混音支持电脑录音
http://blog.csdn.net/cuoban/article/details/50552644
- c#多线程调用有参数的方法
Thread (ParameterizedThreadStart) 初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托. Thread (ThreadStart) 初始 ...
- Sharepoint配置Projectserver
1 需要创建一个project server application 程序. 2 创建一个内容数据库,这个比较简单,微软文档中如下表述: 3 创建一个Project Web App 需要用命 ...
- SVN global ignore pattern
*.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store */bin */ ...
- Linux操作NFS挂载、卸载等操作
一.NFS服务器的设置 NFS服务器的设定可以通过/etc/exports这个文件进行,设定格式如下 分享目录 主机名或IP(参数1,参数2) /binbin 172.17.1.*(rw,sync,n ...
- Linux下的Mysql的双向同步
在主从复制的基础上实现双向同步 [更多参考] https://www.cnblogs.com/shuidao/p/3551238.html http://blog.csdn.net/i_bruce/a ...
- php懈垢windows通用上传缺陷
#1 实例介绍本案例采用的实例是:U-Mail邮件系统.U-Mail邮件系统文件上传的地方代码是这样的: code 区域 <?php if(ACTION =="attach-uploa ...