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 //平均薪水最高的部门编号和名称 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;