http://127.0.0.1:5560/isqlplus
sqlplus sys/manager as sysdba;
alter user scott account unlock;解锁
desc emp|dept;
desc salgrade;
select * from dept;
select ename,sal*12 from emp;
select 2*3 from dual;
select sysdate from dual;
select ename,sal*12 anuual_sal from emp;
select ename,sal*12 "sal total" from emp;
select sal*12+comm from emp;
select ename,sal*12+comm from emp;
select ename||sal from emp;//连接字符串
select ename||'fsdfgdfg' from emp;
select ename||'dsdsdsd''dsdsdsd';//显示单引号
select distinct deptno from emp;
select distinct deptno ,job from emp;//组合重复的去掉
select * from emp where deptno=10;
select * from emp where ename='clack';
select ename from emp where sal>1500;
select ename,sal from emp where deptno<>10;
select ename,sal from emp where ename>'cba';
select ename ,sal from emp where sal between 800 and 1500;
select ename,sal from emp where sal >800 and sal<1500;
select ename,sal from emp where comm is null;
select ename,sal ,comm from emp where sal in(800,1500,2000);
select ename,hiredate from emp where hiredate>'20-2月-81';
select ename from emp where ename like '%all%';
select ename from emp where ename like '%\%%';
select ename from emp where ename like '%¥%' escape ‘¥’;
select * from dept order by deptno desc;
select empno ,ename from emp order by deptno asc;
select ename,empno from emp where deptno<>10 order by empno desc;
select ename from emp order by deptno asc,ename desc;
select lower(ename) from emp;
select ename from emp where lower(ename) like '_a%';
select substr(ename,1,3) from emp;//从第一个开始截截取三个字符
select ascii('A') from dual;
select round(23.652) from dual;//四舍五入
select round(23.652,2) from dual;
select to_char(sal,'$99,999.9999') from emp;//格式转换
select to_char(sal,'L99,999.9999') from emp;//L代表人民币
select to_char(sal,'L00000.0000') from emp;
select to_char(hiredate,'YYYY-MM-DD HH:MI:SS') from emp;
select to_char(sysdate,'YYYY-MM-DD HH:MI:SS') from dual;
conn 用户名/密码
select ename, hiredate from emp where hiredate>to_date('1981-2-20 12:34:56','YYYY-MM-DD HH24:MI:SS');
select sal from emp where sal>to_number('$1,250.00','$9,999.99');
select ename ,sal*12+nvl(comm,0) from emp;
组函数
select max(sal),min(sal),avg(sal) from emp;
select to_char(avg(sal),'99999999.99') from emp;
select sum(sal) from emp;
select count(*) from emp where deptno=10;
select count(distinct deptno) from emp;//查看有多少个唯一的部门编号
select deptno,avg(sal) from emp group by deptno;
select max(sal) from emp group by deptno,job;
select ename,max(sal) from emp;//这是错误的,因为输出不一致
select ename,max(sal) from emp group by deptno;//错误,也许一个组中最大值有几个人
select deptno,max(sal) from emp group by deptno;//正确,查询字段必须是出现在组函数或group by中
select avg(sal),deptno from emp group by deptno;
select avg(sal),deptno from emp group by deptno having avg(sal)>2000;
//having是对分组进行限制
select * from emp
where sal>1800
group by deptno
having
order by
select ename from emp where sal=(select max(sal) from emp);//工资最高
select ename ,sal from emp where sal>(select avg(sal) from emp);//平均薪水之上的人
select ename,sal ,deptno from emp where sal in (select max(sal) from emp group by deptno);
ed;在文本中编辑
/;执行上一条
select ename,sal from emp
join(select max(sal) max_sal,deptno from emp group by deptno)t
on(emp.sal=t.max_sal and emp.deptno=t.deptno);
//部门里面那些人工资最高
select e1.ename,e2.ename
from emp e1,emp e2 where e1.empno = e2.mgr;
sql1999语法
select ename,dname from emp cross join dept;//交叉连接
select ename,dname from emp ,dept where emp.deptno=dept.deptno;(92年语法)
select ename,dname from emp join dept on(emp.deptno=dept.deptno);
等值连接:select ename,dname from emp join dept using(deptno);
select ename,grade from emp e join salgrade s on(e.sal between s.losal and s.hisal);
select ename,dname,grade from
emp e join dept on (e.deptno=d.deptno)
join salgrade s on(e.sal between s.losal and s.hisal)
where ename ont like '_A%';
select e1.ename,e2.ename from emp e1 full|left|right(outer) join emp e2 on(e1.mgr=e2.empno);
select distinct sal from emp where sal not in(select distinctt e1.sal from
emp e1 join emp e2 on(e1.sal<e2.sal));
//平均薪水最高的部门编号和名称
select deptno,avg_sal from (select avg(sal),deptno from emp group by deptno)
where avg_sal=
(select max(avg_sal) from
(select deptno,avg(sal) avg_sal from emp group by deptno));
组函数可以嵌套
//平均薪水等级最低的部门名称
select dname,t1.deptno,grade,avg_sal from(
select deptno ,grade,avg_sal from
(select deptno,avg(sal) avg_sal from emp group by deptno) t
join salgrade s on(t.avg_sal between s.losal and s.hisal)
)t1
where t1.grade=
(
select min(grade) from(
select deptno ,grade,avg_sal from
(select deptno,avg(sal) avg_sal from emp group by deptno) t
join salgrade s on(t.avg_sal between s.losal and s.hisal)
)
);
//视图
create view v$dept_avg_sal_info as
select deptno ,grade,avg_sal from
(select deptno,avg(sal) avg_sal from emp group by deptno) t
join salgrade s on(t.avg_sal between s.losal and s.hisal)
)
//权限不足
conn sys/manager as sysdba;
grant create table,create view to scott;
//平均薪水等级最低的部门名称
select dname,t1.deptno,grade,avg_sal from(
v$dept_avg_sal_info t1
where t1.grade=
(
select min(grade) from v$dept_avg_sal_info
);
部门经理人中平均薪水最低的部门名称
比普通员工的最高薪水还要高的经理人名称
select ename from emp
where empno in(select distinct mgr from emp where mgr is not null)
and sal>(
select max(sal) from emp where empno not in
(select distict mgr from emp where mgr is not null);
)
面试题
比较一下两语句的效率
select * from emp where deptno =10 and ename like '%A%';
select * from emp where ename like '%A%' and deptno=10;
先比较数字,这样效率高,数据库优化后就无法比较了
DML数据库操作语言
drop user zsj;
drop user zsj cascade;
备份backup scott
exp
步骤
exp
scott/tiger
回车
create user zsj(用户名) identified by zsj(密码) default tablespace users quota(配额) 10M on users;
grant create session,create table,create view to liuchao;
导入数据
imp
zsj/zsj
回车
用户名:scott
回车
desc dept;
insert into dept values(50,'game','beijing');
create table emp2 as select * from emp;
insert into dept2 select * from dept;
第二天
select ename,empno from emp;
select empno,ename from emp where rownum<5;
select ename,empno from emp where rownum>10;(错误记住)【条件不能是等于和大于】
select rownum r,ename from emp;
select ename from (select rownum r,ename from emp) where r>10;
薪水最高的五个人
select ename,sal from emp order by sal desc;
select ename,sal from (select ename,sal from emp order by sal desc) where rownum<=5;
第六个到第十个人的薪水
select ename,sal from (
select ename,sal ,rownum r from (select ename,sal from emp order by sal desc)
)where r>=6 and r<=10;
rownum+效率最高+select嵌套
update emp set sal=sal*2,ename=enam||'-' where deptno = 10;
delete from emp where empno<25;
rollback;(后悔了撤销)
drop table t;
事务开始于DML语句(rollback,commit)
事务控制语句
rollback;回退语句
commit;
当遇到ddl[数据定义语言](create table)语句是事务自动提交
exit正常断开连接事务自动提交
dcl(grant语句)数据控制语句
常用[由于效率问题,分为定长字符串和变长字符串,定长的效率高]
create table t(
id varchar2(20),
name char(20),
age number(8,3),
date date,
pid long(4096字节),//可以存文章
content blog
);
create table student(
stuId number(6),
stuName varchar2(20) constraint stu_name_nn not null,(非空约束)
sex number(1),
age number(3),
sdate date,
grade number(2) default 1,
class number(4),
email varchar2(50) unique//唯一约束
);
空值不受unique约束
表级约束
create table student(
stuId number(6) primary key,
stuName varchar2(20) constraint stu_name_nn not null,
sex number(1),
age number(3),
sdate date,
grade number(2) default 1,
class number(4),
email varchar2(50),
constraint stu_name_email_uni unique(email,name)//这两个组合不能重复
);
create table student(
stuId number(6),
stuName varchar2(20) constraint stu_name_nn not null,
sex number(1),
age number(3),
sdate date,
grade number(2) default 1,
class number(4) references class(id),
email varchar2(50),
constraint stu_name_email_uni unique(email,name),//这两个组合不能重复
constraint stu_id primary key (stuId),
constraint stu_class_fk foreign key(class) reference class(id)
);
create table class(
id number(4) primary key,//外键约束被参考的字段一定是主键
name varchar2(20) not null,
)
alter table zsj add(addr varchar2(100));
alter table zsj drop(addr);
alter table zsj modify(addr varchar2(150));
alter table stu drop constraint stu_class_fk;
alter table stu add constraint stu_class_fk foreign key(class) references class(id);
数据字典表
desc user_tables;
select table_name from user_tables;
select view_name from user_views;
select constraint_name from user_constraints;
desc user_constraints;
select constraint_name,table_name from user_constraints;
desc disctionary;
select table_name from dictionary;
索引
create index idx_stu_email on stu(email);
drop index idx_stu_email;
select index_name from user_indexs;
视图的建立是为简化查询,但维护代价也大,同时视图还可以保护数据信息
create view v$stu as select id ,name ,age from stu;
create table article(
id number,
title varchar2(1024),
cont long
);
create sequence seq;
select seq.nextval from dual;
drop sequence seq;
一范式:要有主键,列不可分,不可重复
二范式:不存在部分依赖
三范式:不存在非主属性的传递依赖
第三天(PLSQL)
PL语言是补充SQL语言
begin
dbms_output.put_line('hello world!');
end;
set serveroutput on;
begin
dbms_output.put)line('Hello world');
end;
declare
v_name varchar2(20);
begin
v_name:='myname';
dbms_output.put_line(v_name);
end;
declare
v_number:=0;
v_number:=2/v_number;
dbms_output.put_line(v_number);
exception
when others then
dbms_output.put_line('error');
end;
oracle变量声明规则
1、变量名不能使用保留字,如from ,select
2、第一个字母必须是字符
3、变量名最多包含30个字符
4、不要与数据库的表或列同名
5、每一行只能声明一个变量
--常用变量
1、binary_integer :整数,主要用来计数而不是用来表示字段类型
2、number:数字类型
3、char:定长字符串
4、varchar2:变长字符串
5、date:日期
6、long:长字符串,最长2GB
7、boolean:布尔类型,可以取值true、false和null的值
--变量声明
declare
v_temp number(1);
v_count binary_integer:=0;
v_sal number(7,2):=4000.00;
v_date date:=sysdate;
v_pi constant number(3,2):=3.14;
v_valid boolean:=false;
v_name varchar2(20) not null:='Myname';
begin
dbms_output.put_line('v_temp value:'||v_temp);
end;
布尔类型的值是无法打印出来的
变量声明,使用%type属性
declare
v_empno number(4);
v_empno2 emp.empno%type;
v_empno3 v_empno2%type;
begin
dbms_output.put_line("Test");
end;
--table类型(数组)
declare
type type_table_emp_empno(类型名) is table of emp.empno%type index by binary_integer;
v_empnos type_table_emp_empno;
begin
v_empnos(0):=7369;
v_empnos(2):=7839;
v_empnos(-1):=9999;
dbms_output.put_line(v_empno(-1));
end;
--Record变量类型(复合类型,相当于类)
declare
type type_record_dept is record
(
deptno dept.deptno%type,
dname dept.dname%type,
loc dept.loc%type
);
v_temp type_record_dept;
begin
v_temp.deptno:=50;
v_temp.dname:='aaaa';
v_temp.loc:='bj';
dbms_output.put_line(v_temp.deptno||' '|| v_temp.name);
end;
--使用%rowtype声明record变量
declare
v_temp dept%rowtype;
begin
v_temp.deptno:=50;
v_temp.dname:='aaaa';
v_temp.loc:='bj';
dbms_output.put_line(v_temp.deptno||' '||v_temp.dname);
end;
--SQL语句的使用
declare
v_name emp.ename%type;
v_sal emp.sal%type;
begin
select ename,sal into v_name,v_sal from emp where empno=7369;
dbms_output.put_line(v_name||' '||v_sal);
end;
select语句只能返回一条记录
declare
v_deptno emp.deptno%type:=50;
v_count number;
begin
update emp set sal=sal/2 where deptno=v_deptno;
--select deptno into v_deptno from emp where empno=7369;
--select count(*) into v_count from emp;
dbms_output.put_line(sql%rowcount||'条纪录被影响');
commit;
end;
DCL语句(grant)
DDL(数据定义语言)
begin
execute immdiate 'create table T(nnn varchar2(20) default ''aaa''';
end;
--if语句
--取出7369的薪水,如果小于1200,则输出‘low’,如果《2000则输出‘middle’
declare
v_sal emp.sal%type;
begin
select sal into v_sal from emp
where empno=7369;
if(v_sal<1200) then
dbms_output.put_line("low");
elseif(v_sal<2000) then
dbms_output.put_line("middle");
else
dbms_output.put_line("high");
end if;
end;
--循环语句
declare
i binary_integer:=1;
begin
loop
dbms_output.put_line(i);
i:=i+1;
exit when(i>=j+11);
end loop;
end;
declare
j binary_integer:=1;
begin
while j<11 loop
dbms_output.put_line(j);
j:=j+1;
end loop;
end;
begin
for k in 1..10 loop
dbms_output.put_line(k);
end loop;
for k in reverse 1..10 loop
dbms_output.put_line(k);
end loop;
end;
--错误处理
declare
v_temp number(4)
begin
select empno into v_temp from emp where deptno=10;
exception
when too_many_rows then
dbms_output.put_line("太多记录了");
when others then
dbms_output.put_line("error");
end;
declare
v_temp number(4);
begin
select empno into v_temp from emp where empno=2222;
exception
when no_data_found then
dbms_output.put_line("没数据");
end;
create table errorlog(
id number primary key,
errcode number,
errmsg varchar2(1024),
errdate date
);
create sequence seq_errorlog_id start with 1 increment by 1;
declare
v_deptno dept.deptno%type:=10;
v_errcode number;
v_errmsg varchar2(1024);
begin
delete from dept where deptno=v_deptno;
commit;
exception
when others then
rollback;
v_errcode:=SQLCODE;
v_errmsg:=SQLERRM;
insert into errorlog values(seq_errorlog_id.nextval,v_errmsg,sysdate);
commit;
end;
--游标
declare
cursor c is
select * from emp;
v_temp c%rowtype;
begin
open c;
fetch c into v_temp;
dbms_output.put_line(v_temp.ename);
close c;
end;
declare
cursor c is
select * from emp;
v_temp c%rowtype;
begin
open c;
loop
fetch c into v_emp;
exit when (c%notfound);
dbms_output.put_line(v_emp.ename);
end loop;
close c;
end;
如果没有截取到指针的值,则则会将上一次的值作为这一次的值
declare
cursor c is
select * from emp;
v_temp c%rowtype;
begin
open c;
fetch c into v_temp;
loop
while(c%notfound) loop
dbms_output.put_line(v_emp.ename);
fetch c into v_temp;
end loop;
close c;
end;
declare
cursor c is
select * from emp;
begin
for v_emp in c loop
dbms_output.put_line(v_emp.ename);
end loop;
end;
--带参数的游标
declare
cursor c(v_deptno emp.deptno%type,v_job emp.job%type)
is
select ename,sal from emp where deptno=v_deptno and job=v_job;
--v_temp c%rowtype;
begin
for v_temp in c(30,'CLERK') loop
dbms_output.put_line(v_temp.ename);
end loop;
end;
--可更新的游标
declare
cursor c
is
select * from emp for update;
--v_temp c%rowtype;
begin
for v_temp in c loop
if(v_temp.sal<2000) then
update emp set sal=sal*2 where current of c;
elseif(v_temp.sal=5000)then
delete from emp where current of c;
end if;
end loop;
commit;
end;
第四天
存储过程
create or replace procedure p
is
cursor c is
select * from emp for update;
begin
for v_temp in c loop
if(v_temp.deptno=10)then
update emp set sal=sal+10 where current of c;
elseif(v_temp.deptno=20)then
update emp2 set sal=sal+20 where current of c;
else
update emp set sal=sal+50 where current of c;
end loop;
commit;
end;
执行存储过程
1、exec p;
2、begin
p;
end;
带参数的存储过程
create or replace procedure p
(
v_a in number,v_b number,v_ret out number,v_temp in out number
)
is
begin
if(v_a>v_b)then
v_ret:=v_a;
else
v_ret:=v_b;
end if;
v_temp:=v_temp+1;
end;
调用存储过程
declare
v_a number;+3;
v_b number:=4;
v_ret number;
v_temp:=5;
begin
p(v_a,v_b,v_ret,v_temp)
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
show error;
drop procedure p;
函数
create or replace function sal_tax
(v_sal number)
return number
is
begin
if(v_sal<2000)then
return 0.10;
elseif(v_sal<2700)then
return 0.15;
else
return 0.20;
end if;
end;
触发器
create table emp_log
(
uname varchar2(20),
action varchar2(10),
atime date
);
create or replace trigger trig
after insert or delete or update on emp for each row
begin
if inserting then
insert into emp_log values(USER,'insert',sysdate);
elseif updating then
insert into emp_log values(USER,'update',sysdate);
elseif deleting then
insert into emp_log values(USER,'delete',sysdate);
end if;
end;
update emp set sal=sal*2 where deptno=30;
select * from emp_log;
update dept set deptno=99 where deptno=10;
drop trigger trig;
create or replace trigger trig
after update on dept
for each row
begin
update emp set deptno:=NEW.deptno where deptno=:OLD.deptno;
end;
select * from emp;
rollback;
create table article(
id number primary key,
cont varchar2(4000),
pid number,
isleaf number(1),--0代表非叶子节点,1代表叶子节点
alevel number(2)
);
create or replace procedure p(v_pid article.pid%type,v_level binary_integer) is
cursor c is select * from article where pid=v_pid;
v_prestr varchar2(1024):="";
begin
for i in 1..v_level loop
v_prestr:=v_prestr||'****';
end loop;
for v_article in c loop
dbms_output.put_line(v_prestr||v_article.cont);
if(v_article.isleaf=0) then
p(v_article.id,v_level+1);
end if;
end loop;
end;
exec p(0,0);
set serveroutput on;