1.语句:
-- 查询语句创建表
create table emp as select * from scott.emp;
select * from emp;
-- 创建视图[必须有dba权限]
create view v_emp as select ename, job from emp;
-- 查询视图
select * from v_emp;
-- 修改视图[不推荐]
update v_emp set job='CLERK' where ename='ALLEN';
-- 创建只读视图
create view v_empl as select ename, job from emp with read only;
2. 视图的作用?
-- 第一:视图可以屏蔽掉一些敏感字段
-- 第二:保证总部和分部数据及时统一;[视图没有数据,数据是从总部获取的,当总部修改了后,分部就立即修改了]
索引
1. 索引的概念:索引就是在表的列上构建一个二叉树,达到大幅度提高查询效率的目的,但是索引会影响增删改的效率
2. 单列索引
-- 创建单列索引
create index idx_ename on emp(ename);
-- 单列索引触发规则,条件必须是索引列中的原始值
-- 单行函数,模糊查询,都会影响索引的触发
select * from emp where ename='SCOTT';
3. 复合索引
-- 创建复合索引
create index idx_enamejob on emp(ename,job);
-- 如果要触发复合索引,必须包含有优先检索列中的原始值
select * from emp where ename='SCOTT' and job='xx'; -- 触发复合索引
select * from emp where ename='SCOTT' or job='xx'; --不触发索引[一个触发,一个不触发,那么就是不触发索引了]
select * from emp where ename='SCOTT'; -- 触发单列索引。
pl/sql编程语言
1. 概述:
-- pl /sql 编程语言
-- pl/sql 编程语言是对sql语言的扩展,使得sql语言具有过程化编程的特性。
-- pl/sql 变成语言比一般的过程化编程语言,更加灵活高效。
-- pl/sql编程语言主要用来编写存储过程和存储函数等。
2. 声明方法
-- 赋值操作可以使用:= 也可以使用查询语句赋值
declare
i number(2):=10;
s varchar2(10):='小明';
ena emp.ename%type; -- 引用型变量
emprow emp%rowtype; -- 记录型变量 【查询一行的记录】
begin
dbms_output.put_line(i);
dbms_output.put_line(s);
select ename into ena form emp where empno=7788;
dbms_output.put_line(ena);
select * into emprow form emp where empno=7788;
dbms_output.put_line(emprow.ename || '的工作为' || emprow.job); //在orcale中连接符不是+ ,而是||
end;
3. pl/sql中的if判断
-- 输入小于18的数字,输出未成年
-- 输入大于18 小于40的数字,输出中年人
-- 输入大于40的数字,输出老年人
declare
i number(3):=ⅈ
begin
if i<18 then
dbms_output.put_line('未成年');
elsif i<40 then
dbms_output.put_line('中年人');
else
dbms_output.put_line('老年人');
end if;
end;
4. pl/sql中的loop循环
1. 用三种方式输出1到10 十个数字
1. while循环
declare
i number(2):=1;
begin
while i<22 loop
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
2. exit 循环 //工作中用的多,掌握
declare
i number(2):=1;
begin
loop
exit when i>10;
i:i+1;
end loop;
end;
3. for循环
declare
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
5. 游标:可以存放多个对象,多行记录。
-- 输出emp表中所有员工的姓名
declare
cursor cl is select * from emp;
emprow emp%rowtype
begin
open c1;
loop
fetch c1 into emprow;
exit when c1%notfound;
dbms_output.put_line(emprow.ename);
end loop;
close c1;
end;
-- 给指定部门员工涨工资
declare
cursor c2(eno emp.deptno%type) is select empno from emp where deptno=eno;
en emp.empno%type;
begin
open c2(10);
loop
fetch c2 into en;
exit when c2%notfound;
update emp set sal=sal+100 where empno=en;
commit;
end loop;
close c2;
end;
-- 查询10号部门员工信息
select * from emp where deptno =10;
存储过程
1.概述:
* 存储过程:存储过程就是提前已经编译好的一段pl/sql语言,放置在数据库端,可以直接被调用。这一段pl/sql一般都是固定步骤的业务。
* 不能写太复杂的业务,不然维护起来会很麻烦;
2. 创建存储过程的语法:
create [or replace] procedure 过程名[(参数名 in/out 数据类型)]
as
begin
PLSQL子程序体;
end;
或者
create [or repalece]procedure 过程名[(参数名 in/out 数据类型)]
is
begin
PLSQL子程序体;
end 过程名;
3.示例:
-- 给指定员工涨100块钱
create or replace procedure pl(eno emp.empno%type) -- 写上replace如果有其他的同名字的该代码可以覆盖,建议加上;
is
begin
update emp set sal=sal+100 where empno=eno;
commit;
end;
select * from emp where empno=7788
-- 测试p1
declare
begin
p1(7788);
end;
-- orcale语法严格,分号也必须加,不然会报错;
-- 创建了存储过程的语句,无论关机后重启打开软件,都能在Procedures目录下找到该存储过程的文件;
存储函数
1. 语法:
create or replace function 函数名(Name in type, Name in type,...)return 数据类型 is 结果变量 数据类型;
begin
return(结果变量);
end 函数名;
-- 通过存储函数实现计算,指定员工的年薪
-- 存储过程和存储函数的参数都不能带长度
-- 存储函数放在Functions目录下
-- 存储函数的返回值类型不能带长度
2.示例:
create or replace function f_yearsql(eno emp.empno%type) return number
is
s number(10);
begin
select sal*12+nvl(comm,0) into s from emp where empno=eno;
return s;
end;
3. 测试f_yearsal
-- 存储函数在调用的时候,返回值需要接收
declare
s number(10);
begin
s:=f_yearsal(7788)
dbms_output.put_line(s);
end;
4. out类型参数如何使用
-- 使用存储过程来算年薪
create or replace procedure p_yearsal(eno emp.empno%type, yearsal out number)
is
s number(10);
c emp.comm%type;
begin
select sal*12, nvl(comm,0) into s,c from emp where empno=eno;
yearsal:=s+c;
end;
5. 测试p_yearsal(7788,yearsal);
declare
yearsal number(10);
begin
p_yearsal(7788,yearsal);
dbms_output.put_line(yearsal);
end;
-- in和out类型的参数的区别是什么?
-- 凡是涉及到into查询语句赋值或者 := 赋值操作的参数,都必须使用out来修饰;
-- 存储过程和存储函数的区别?
-- 语法区别:1.关键字不一样 2. 存储函数比存储过程多了两个return
-- 本质区别:存储函数有返回值,而存储过程没有返回值
-- 如果储存过程想实现有返回值的业务,我们就必须使用out类型的参数
-- 即便是存储过程使用了out类型的参数,其本质也不是真的有了返回值
-- 而是在存储过程内部给out类型参数赋值,在执行完毕后,我们直接其返回值操作。
6.自定义函数
-- 我们可以使用存储函数有返回值的特性,来自定义函数。
-- 而存储过程不能用来自定义函数。
-- 案例需求:查询出员工姓名,员工所在部门名称。
-- 案例准备工作:把scott用户下的dept表复制到当前用户下
crate table dept as select * from soctt.dept;
-- 使用传统方式来实现案例需求
select
from emp e; dept d
where e.deptno=d.deptno;
-- 使用存储函数来是西安提供一个部门编号,输出一个部门名称。
create or replace function fdna(dno dept.deptno%type) return dept.dname%type
is
dna dept.dname%type;
begin
select dname into dna from dept where deptno=dno;
return dna;
end;
-- 使用fdna存储函数来实现案例需求
select e.ename,fdna(e.deptno) -- 这里fdna调用了上面存储过程方法
from emp e;
-- 存储过程和存储函数相当于java中的方法,存储过程用来增删改,存储函数可以用来做查询;
触发器
1.概述:
-- 触发器,就是指定一个规则,在我们做增删改操作的时候,只要满足该规则,自动触发,无需调用。 查询的时候不会调用到触发器;
-- 语句级触发器:不包含有for each row的触发器
-- 行级触发器:包含有for each row 的就是行级触发器
--- 加for each row 为了使用 :old 或者 :new 对象或者一行记录。
-- 数据中的一行数据对应java中的对象
-- insert 的 :old 是所有字段为null,:new 之后就有了新的数据
-- Update 的 :old 是更新以前该行的值, :new 是更新后的值
-- delete 的 :old 是删除之前该行的值, :new 是所有字段都为null
2.示例:
1. 语句级触发器:
-- 插入一条记录,输入一个新员工入职 //触发器示例
create or replace trigger t1
after
insert
on person
declare
begin
dbms_output.put_line('一个新员工入职');
end;
-- 触发t1
insert into person values(1,'小红');
commit;
-- 查询
select * from person;
2. 行级触发器
-- 不能给员工降薪
-- raise_application_error()
create or replace tigger t2
before
update
on emp
for each row
declare
begin
if:old.sal>:new.sal then
raise_application_error(-200001,'不能给员工降薪')
end if;
end;
-- 触发t2
update emp set sal=sal-1 where empno =7788;
commit;
-- 查询
select * form emp where empno=7788;
3. 触发器实现主键自增。[行级触发器]
-- 分析:在用户做插入操作之前,拿到即将插入的数据。
-- 给该数据中的主键列赋值。
create or replace tigger auid
before
insert
on person
for each row
declare
begin
select s_person.nextval into :new.pid from dual;
end;
-- 查询person表数据
select * from person;
-- 使用auid实现主键自增
insert into person (pname) values ('a');
commit;
4. 使用java调用orcale中的存储过程和存储函数
-- orcale10g ojbdc14.jar
-- orcalel11g ojdbc6.jar
示例:
1. 创建一个maven工程 gid:com.itheima aid:jdbc_orcale
2. Maven projects need to be imported?[是否自动导入] ->Enable Auto-Import 确定自动导入
3. pom.xml导入角标:[ojdbc14/runtime,junit/test]
4. test.java.com.itheima.orcale.OrcaleDame:创建该类:
* public class OrcaleDemo{
* @Test
* public void javaCa11Orcale() throws Exception{
* //加载数据库驱动
* Class.forName("orcale.jdbc.driver.OrcaleDriver")
* //得到connection连接
* Connection connection=DriverManager.getConnection("jdbc:orcale:thin:@192.168.88.6:1521:orcale",scott,tiger)
* //得到预编译的Statement对象
* CallableStatement pstm=connection.prepareCall("{call p_yearsal(?,?)}");
* //给参数赋值
* pstm.setObject(1,7788);
* pstm.registerOutParameter(2,OracleType.NUMBER);
* //执行数据库查询操作
* pstm.execute();
* //输出结果
* System.out.println(pstm.getObject("2"));
* pstm.close();
* }