oracle笔记

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;

你可能感兴趣的:(oracle,分组,解锁)