序列:

模拟自增,本质就是内存中的数组

创建格式:

create sequence 序列名;
	increment by 步长;		默认是1
	start with 起始值;		默认是1
	maxvalue	nomaxvalue
	minvalue	nominvalue
	cycle		nocycle
	cache		nocache

两个属性: currval 当前值, nextval 下一个值
序列会接着上一次的值继续使用,不会归零

查看序列

select *from user_sequences;

示例:

新建一个表
	create table person(pid number primary key,pname varchar2(10));
插入数据
	insert into person values(myseq.nextval,'zs');
	insert into person values(myseq.nextval,'ls');
	insert into person values(myseq.nextval,'ww');
创建自定义序列
	create sequence myseq1
	increment by 2
	start with 1
	maxvalue 9
	minvalue 1
	cycle
	cache 3;
	cache元素的个数 <= 循环元素
	1 3 5 7 1 3 5 7 ....

循环序列不能用于给 主键/唯一约束的键 赋值

裂缝:

[1,2,3,4,.....20]
	出现断电、异常、回滚、多表使用同一个序列...
	使用过属性nextval,但是没有存入数据,下次再次使用时,中间有裂缝

修改序列

alter sequence myseq
	increment by 2;
	只对修改以后的操作有效

删除序列:

drop sequence myseq;

索引:

类似于书的目录

索引类型: 默认B树索引(默认) 位图索引

创建索引:

create index 索引名;
	注意: 主键默认就是索引
单层:create index myindex on emp(deptno);
多层:create index myindex1 on emp(deptno,sal);

什么时候适合建立索引?

数据集中的列,经常在where中使用的列,数据量比较大
	数据集中的列:主键列,不集中,但是因为需要频繁使用, 也适合建索引。

删除索引:

drop index myindex;

同义词(别名)

数据库对象(表 视图 索引 …) 起别名 (默认是私有/专用的)

查看hr: employees;

查看其他用户的表,报错“表或视图不存在”  也可能是权限不足导致的
去sys账户授权:  
	grant xxx to 用户名;		grant select on he.employees to scott;
	revoke xxx from 用户名;

查询:

select count(*) from hr.employees;		名字太长

起别名:

create synonym hremp for hr.employees;

再查询时可以

select count(*) from hremp;

创建共有同义词:

create public synonym hremp2 for hr.employees;

删除同义词: drop sysnonym 同义词名;
删除共有同义词: drop public sysnonym 同义词名;
共有同义词的创建和删除,一般建议由管理员来操作。

PLSQL: 对SQL进行编程

开发工具

plsql developer
oracle sql developer

plsql:

declare
	变量、常量、光标(游标)、例外(自定义异常)
begin
	写代码
	exception
		捕获异常
end;

引用型变量:

pname emp.ename%type;		能保存一个值

记录型变量:(相当于java中的对象,同时保存多个变量值)

emp_info emp%rowtype;			能保存一行值
	SELECT * into emp_info FROM emp where empno = 7788;

打印:

dbms_output.put_line(emp_info.empno ||'--'|| emp_info.ename ||'--'|| emp_info.job);

条件语句if:

1.
	if 条件 then...
	end if;
2.
	if 条件 then...
	else ....
	end if;
3.
	if 条件 then...
	elsif 条件 then...
	else ...
	end if;

循环结构 while do…while for

1.
	while 条件 
	loop
	...
	end loop;
2.
	loop
	...
	exit when 退出条件;
	end loop;
3.
	for i in 1..10
	loop
	...
	end loop;

计算 1-5之和

set SERVEROUTPUT ON;
declare
		pnum number:=1;
		psum number :=0;
begin
	loop
		exit when pnum>5;
		psum := psum+pnum;
		pnum := pnum +1;
	end loop; 
	dbms_output.put_line(psum);
end;

游标(光标) cursor:集合

定义语法:
cursor 光标名(参数列表)
		is
		select ...
光标的属性
%isopen				判断光标是否打开
		%rowcount			读取的个数
		%found				判断下一行是否存在数据
		%notfound
查询并打印全部员工的姓名、薪水
setSERVEROUTPUT ON;
declare
		cursor cemp is select ename,sal from emp;
		pename emp.ename%type;
		psal emp.sal%type;
begin
	open cemp;  						--1.打开光标
	loop        						--2.定义循环,准备获取每一行数据
		fetch cemp into pename,psal; 	--3.一行一行的获取光标的值
		exit when cemp%notfound;		--4.使用数据,写跳出循环条件
		dbms_output.put_line(pename||'的工资是'||psal);--
	end loop;
	close cemp; 						--5.关闭光标
end;
涨工资: president 1000,manger 800 其他 400
set SERVEROUTPUT ON;
declare
		cursor cemp is select empno,job from emp;
		pempno emp.empno%type;
		pjob emp.job%type;
begin
	open cemp;  
	loop        
		fetch cemp into pempno,pjob; 
		exit when cemp%notfound;
		if pjob = 'PRESIDENT' then 
			update emp set sal = sal+1000 where empno = pempno;
		elsif pjob = 'MANAGER' then 
			update emp set sal = sal+800 where empno = pempno; 
		else update emp set sal = sal+400 where empno = pempno;
		end if;
	end loop;
	dbms_output.put_line('成功');
	close cemp; --5.关闭光标
	commit; --ACID  oracle read commit,  一边不提交,另一边访问不到
end;
查询某个部门的员工姓名,用带参数的光标来做
set serveroutput on;
	declare
		cursor cename(dno number) is select ename from emp where deptno = dno;
		pename emp.ename%type;
	begin
		open cename(30);
		loop
			fetch cename into pename;
			exit when cename%notfound;
			dbms_output.put_line(pename);
		end loop;
		close cename;
	end;

例外(异常):

系统例外;
no_data_found			没有数据错误
Too_many_rows			行数过多
Value_error	:			算术或转换错误
TimeOut_on_resource:	资源等待超时
系统例外的使用
setserveroutput on;
declare
	pnum number;
begin
   pnum := 1/0;
   exception
		when zero_divide then dbms_output.put_line('0不能作为除数');
		when Too_many_rows then dbms_output.put_line('行数太多');
		when others then dbms_output.put_line('其他例外。。');
end;
自定义例外:
set serveroutput on;
declare
	myexc exception;
	pnum number:=1;
begin
	if pnum = 1 then raise myexc;
	end if;
	exception
		when myexc then dbms_output.put_line('自定义例外');
end;
是否存在编号50部门,如果不存在 抛出异常,如果存在,将该部门的员工姓名打印
setserveroutput on;
declare
	cursor cemp(dno number) is select ename from emp where deptno = dno;
	pename  emp.ename%type;
	no_emp_found exception;
begin
	open cemp(50);
	fetch cemp into pename;
	if cemp%notfound then raise no_emp_found;
	else
		loop
			exit when cemp%notfound;
			fetch cemp into pename;
		end loop;
	end if;
	exception
		when no_emp_found then dbms_output.put_line('没有此号部门');
	close cemp;
end;