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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章