程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> 細數你應該修煉的Oracle基本功

細數你應該修煉的Oracle基本功

編輯:Oracle數據庫基礎

以下的文章,主要為大家在實際工作中提供一種解決方法。

---用戶名:scott

---密  碼:tiger

---*********Oracle表連接與子查詢示例************

---求部門中哪些人的薪水最高

  1. select ename,sal from emp  
  2. join (select max(sal) max_sal, deptno from emp group by deptno) t  
  3. on (emp.sal = t.max_sal and emp.deptno = t.deptno); 

---求部門平均薪水的等級

  1. select deptno,avg_sal,grade from 
  2. (select deptno,avg(sal) avg_sal from emp group by deptno) t  
  3. join salgrade s on (t.avg_sal between s.losal and s.hisal); 

---求部門平均的薪水等級

  1. select deptno,avg(grade) from 
  2. (select deptno,ename,grade from emp join salgrade s on (emp.sal between s.losal and s.hisal)) t  
  3. group by deptno; 

---雇員中哪些人是經理人

  1. select ename from emp where empno in (select distinct mgr from  emp); 

---不用組函數,求薪水的最高值

  1. select sal from emp where sal not in 
  2. (select distinct e1.sal from emp e1 join emp e2 on (e1.sal < e2.sal)); 

---用組函數,求薪水的最高值

  1. select max(sal) from emp; 

---求平均薪水最高的部門的部門編號

  1. select deptno , avg_sal from 
  2.  (select avg(sal) avg_sal,deptno from emp group by deptno) t  
  3. where avg_sal =  
  4.  (select  max(avg_sal) from (select avg(sal) avg_sal,deptno from emp group by deptno) t); 

----組函數嵌套的寫法

  1. select deptno , avg_sal from 
  2.  (select avg(sal) avg_sal,deptno from emp group by deptno) t  
  3. where avg_sal =  
  4.  (select  max(avg(sal)) from emp group by deptno); 

---求平均薪水最高的部門的名稱

  1. select dname from dept   
  2. where deptno =  
  3. (  
  4.  select deptno from 
  5.  (select avg(sal) avg_sal,deptno from emp group by deptno) t  
  6.  where avg_sal =  
  7.  (select  max(avg_sal) from (select avg(sal) avg_sal,deptno from emp group by deptno) t)  
  8. ); 

---求平均薪水的等級最低的部門的部門名稱

  1. select avg(sal) avg_sal,deptno from emp group by deptno  

--部門平均薪水

  1. select min(avg_sal) from 
  2. (  
  3. select avg(sal) avg_sal,deptno from emp group by deptno  

--平均工資的最小值

  1. select avg_sal,deptno from   
  2. (select avg(sal) avg_sal,deptno from emp group by deptno) t  
  3. where avg_sal =  
  4. (  
  5. select min(avg_sal) from 
  6. (  
  7. select avg(sal) avg_sal,deptno from emp group by deptno  
  8. )  

--平均工資的最小值及部門編號

  1. select t.avg_sal,t.deptno,s.grade from   
  2. (select avg(sal) avg_sal,deptno from emp group by deptno) t  
  3. join salgrade s on (t.avg_sal between s.losal and s.hisal)   
  4. where avg_sal =  
  5. (  
  6. select min(avg_sal) from 
  7. (  
  8. select avg(sal) avg_sal,deptno from emp group by deptno  
  9. )  

--平均工資的最小值及部門編號和工資等級

  1. select d.dname,t.avg_sal,t.deptno,s.grade from   
  2. (select avg(sal) avg_sal,deptno from emp group by deptno) t  
  3. join salgrade s on (t.avg_sal between s.losal and s.hisal)   
  4. join dept d on (t.deptno = d.deptno)  
  5. where avg_sal =  
  6. (  
  7. select min(avg_sal) from 
  8. (  
  9. select avg(sal) avg_sal,deptno from emp group by deptno  
  10. )  

--平均工資的最小值及部門編號和工資等級及部門名稱

----Another 按照題意的寫法

  1. select t1.deptno,t1.avg_sal,grade,d.dname from 
  2. (  
  3. select deptno,avg_sal,grade from 
  4. (select deptno,avg(sal) avg_sal from emp group by deptno) t  
  5. join salgrade s on (t.avg_sal between s.losal and s.hisal)  
  6. ) t1  
  7. join dept d on (t1.deptno = d.deptno)   
  8. where grade =  
  9. (   
  10. select min(grade) from 
  11. (  
  12. select deptno,avg_sal,grade from 
  13. (select deptno,avg(sal) avg_sal from emp group by deptno) t  
  14. join salgrade s on (t.avg_sal between s.losal and s.hisal)  
  15. )  
  16. ); 

---創建視圖或者表,如果沒有權限

  1. conn sys/sys as sysdba; 

--已連接。

  1. grant create tablecreate vIEw to scott; 

--授權成功。

---創建視圖

  1. create vIEw v$_dept_avg_sal_info as 
  2.   select deptno,avg_sal,grade from 
  3. (select deptno,avg(sal) avg_sal from emp group by deptno) t  
  4. join salgrade s on (t.avg_sal between s.losal and s.hisal); 

--視圖已建立。

---創建這個v$_dept_avg_sal_info視圖可以簡化上面那個查詢的重復代碼

  1. select t1.deptno,t1.avg_sal,grade,d.dname from 
  2. v$_dept_avg_sal_info t1  
  3. join dept d on (t1.deptno = d.deptno)   
  4. where grade =  
  5. (   
  6. select min(grade) from 
  7. v$_dept_avg_sal_info  
  8. ); 

---求比普通員工的最高薪水還要高的經理的名稱

  1. select max(sal) from emp where empno not in 
  2. (select distinct mgr from emp where mgr is not null); 

--普通員工的最高薪水

  1. select ename from emp   
  2. where empno in (select distinct mgr from emp where mgr is not null)  
  3. and sal >  
  4. (  
  5. select max(sal) from emp where empno not in(select distinct mgr from emp where mgr is not null)  
  6. ); 

--普通員工的最高薪水還要高的經理的名稱

--- Oracle 聯機歸檔日志 備份方式

---求薪水最高的第6名到第10名雇員(rownum)

  1. select ename,sal from 
  2. (select ename,sal,rownum r from 
  3. (  
  4. select ename, sal from emp order by sal desc 
  5. )  
  6. where r>=6 and r<=10; 

---五種約束條件

  1. create table stu  
  2. (   
  3. id number(2),  
  4. name varchar2(20) constraint stu_name_nn not null,--非空約束  
  5. sex  number(2),  
  6. age number(3),  
  7. sdate date,  
  8. grade number(3) default 1,  
  9. class number(3),  
  10. email varchar2(50),  
  11. constraint stu_name_email_uin unique(name,email)--唯一主鍵  
  12. ) ;  
  13.  
  14.  
  15. insert into stu(name,email) values('','[email protected]'
  16. --ORA-01400: 無法將 NULL 插入 ("SCOTT"."STU"."NAME")  
  17.  
  18.  
  19. insert into stu(name,email) values('tianyuexing','[email protected]');  
  20. insert into stu(name,email) values('tianyuexing','[email protected]');
  21. --ORA-00001: 違反唯一約束條件 (SCOTT.STU_NAME_EMAIL_UIN) 

---PL/SQL 一個簡單的存儲過程 分為四塊1.聲明declare 2.begin 3.exception 4.end

  1. set serveroutput on;  
  2.  declare 
  3. v_num number :=0;  
  4. begin 
  5. v_num :=2/v_num;  
  6. dbms_output.put_line(v_num);  
  7. exception  
  8. when others then 
  9. dbms_output.put_line('error');  
  10. end

---%type 變量聲明的好處。

  1. declare 
  2. v_empno2 emp.empno%type;  
  3. begin 
  4. dbms_output.put_line('test');  
  5. end

---Table 變量類型

  1. declare 
  2. type type_table_emp_empno is table of emp.empno%type index by binary_integer;  
  3. v_empnos type_table_emp_empno;  
  4. begin 
  5. v_empnos(0) := 2999;  
  6. v_empnos(1) := 2434;  
  7. v_empnos(-1) := 8989;  
  8. dbms_output.put_line(v_empnos(-1));  
  9. end

---Record 變量類型

  1. declare 
  2. type type_record_dept is record  
  3. (  
  4. deptno dept.deptno%type,  
  5. dname  dept.dname%type,  
  6. loc dept.loc%type  
  7. );  
  8. v_temp type_record_dept;  
  9. begin 
  10. v_temp.deptno := 20;  
  11. v_temp.dname := 'tianyuexing';  
  12. v_temp.loc := 'qhd';  
  13. dbms_output.put_line(v_temp.dname || ' ' ||v_temp.loc);  
  14. end

---使用 %rowtype聲明record變量

  1. declare 
  2. v_temp dept%rowtype;  
  3. begin 
  4. v_temp.deptno := 20;  
  5. v_temp.dname := 'yuexingtian';  
  6. v_temp.loc := 'qhd';  
  7. dbms_output.put_line(v_temp.dname || ' ' ||v_temp.loc);  
  8. end

---SQL語句的運用

  1. declare 
  2. v_ename emp.ename%type;  
  3. v_sal emp.sal%type;  
  4. begin 
  5. select ename,sal into v_ename,v_sal from emp where empno = 7369;  
  6. dbms_output.put_line(v_ename ||' '||v_sal);  
  7. end;  
  8.  
  9.  
  10. declare 
  11. v_emp emp%rowtype;  
  12. begin 
  13. select * into v_emp from emp where empno = 7369;  
  14. dbms_output.put_line(v_emp.ename);  
  15. end;  
  16. --insert 語句  
  17. declare 
  18. v_deptno dept.deptno%type := 50;  
  19. v_dname dept.dname%type :='yuexingtian';  
  20. v_loc dept.loc%type := '秦皇島';  
  21. begin 
  22. insert into dept2 values (v_deptno,v_dname,v_loc);  
  23. commit;  
  24. end

---sql%rowcount 多少條記錄被影響

  1. declare 
  2. v_deptno emp2.deptno%type := 10;  
  3. v_count number;  
  4. begin 
  5. update emp2 set sal = sal/2 where deptno = v_deptno;  
  6. dbms_output.put_line(sql%rowcount ||'條記錄被影響');  
  7. end

--create語句

  1. begin 
  2. execute immediate 'create table T (nnn varchar2(20) default ''yuexingtian'')';  
  3. end

---if語句,取出7369的薪水,如果<1200,則輸出'low',如果<2000則輸出'middle',否則輸出'high'.

  1. declare 
  2. v_sal emp.sal%type;  
  3. begin 
  4. select sal into v_sal from emp  
  5. where empno = 7369;  
  6. if(v_sal < 1200) then 
  7. dbms_output.put_line('low');  
  8. elsif(v_sal < 2000) then 
  9. dbms_output.put_line('middle');  
  10. else 
  11. dbms_output.put_line('high');  
  12. end if;  
  13. end

---循環 loop (相當於do while)

  1. declare 
  2. i binary_integer := 1;  
  3. begin 
  4. loop  
  5. dbms_output.put_line(i);  
  6. i := i+1;  
  7. exit when (i>=11);  
  8. end loop;  
  9. end;   
  10. ---when ……loop (相當於while)  
  11. declare 
  12. j binary_integer := 1;   
  13. begin 
  14. while j<11 loop  
  15. dbms_output.put_line(j);  
  16. j := j+1;  
  17. end loop;  
  18. end;   
  19. ---for ...in... loop   
  20. begin 
  21. for k in 1..10 loop  
  22. dbms_output.put_line(k);  
  23. end loop;  
  24. for k in reverse 1..10 loop --逆序  
  25. dbms_output.put_line(k);  
  26. end loop;   
  27. end

--- 異常處理

  1. declare 
  2. v_temp number(4);  
  3. begin 
  4. select empno into v_temp from emp where deptno = 10;  
  5. exception  
  6. when too_many_rows then --多條記錄的異常  
  7. dbms_output.put_line('記錄太多了');  
  8. when others then 
  9. dbms_output.put_line('error');  
  10. end;  
  11.  
  12.  
  13. declare 
  14. v_temp number(4);  
  15. begin 
  16. select empno into v_temp from emp where empno = 4444;  
  17. exception  
  18. when no_data_found then 
  19. dbms_output.put_line('沒有數據');  
  20. end

---記錄數據庫錯誤信息的errorlog

  1. create table errorlog  
  2. (  
  3. id number primary key,  
  4. errcode number,  
  5. errmsg varchar2(1024),  
  6. errdate date 
  7. );  
  8.  
  9.  
  10. create sequence seq_errorlog_id start with 1 increment by 1; --創建遞增序列  
  11.  
  12.  
  13. --PL/SQL  
  14. declare 
  15. v_deptno dept.deptno%type :=10;  
  16. v_errcode number;  
  17. v_errmsg varchar2(1024);  
  18. begin 
  19. delete from dept where deptno = v_deptno;  
  20. commit;  
  21. exception  
  22. when others then 
  23. rollback;  
  24. v_errcode := SQLCODE;  
  25. v_errmsg := SQLERRM;  
  26. insert into errorlog values (seq_errorlog_id.nextval,v_errcode,v_errmsg,sysdate);  
  27. commit;  
  28. end;  
  29.  
  30.  
  31. select to_char(errdate,'YYYY-MM-DD HH24:MI:ss'from errorlog; ---具體的出錯時間。 

---游標

  1. declare 
  2. cursor c is   
  3. select * from emp;  
  4. v_emp c%rowtype;  
  5. begin 
  6. open c;  
  7. fetch c into v_emp;  
  8. dbms_output.put_line(v_emp.ename);  
  9. close c;  
  10. end;  
  11. ---游標,循環取出所有的記錄。  
  12. declare 
  13. cursor c is 
  14. select * from emp;  
  15. v_emp c%rowtype;  
  16. begin 
  17. open c;  
  18. loop  
  19. fetch c into v_emp;  
  20. exit when (c%notfound);  
  21. dbms_output.put_line(v_emp.ename);  
  22. end loop;  
  23. close c;   
  24. end;   
  25. ---游標while 循環  
  26. declare 
  27. cursor c is 
  28. select * from emp;  
  29. v_emp c%rowtype;  
  30. begin 
  31. open c;  
  32. fetch c into v_emp;  
  33. while (c%found) loop  
  34. dbms_output.put_line(v_emp.ename);  
  35. fetch c into v_emp;  
  36. end loop;  
  37. close c;  
  38. end;   
  39. ---for循環 不用聲明變量,不用open游標 不用close游標 不用fetch  
  40. declare 
  41. cursor c is   
  42. select * from emp;  
  43. begin 
  44. for v_emp in c loop  
  45. dbms_output.put_line(v_emp.ename);  
  46. end loop;  
  47. end

---帶參數的游標

  1. declare 
  2. cursor c(v_deptno emp.deptno%type, v_job emp.job%type)  
  3. is 
  4. select ename,sal from emp where deptno = v_deptno and job = v_job;  
  5. begin 
  6. for v_temp in c(30,'CLERK') loop  
  7. dbms_output.put_line(v_temp.ename);  
  8. end loop;  
  9. end

---課更新的游標

  1. declare 
  2. cursor c   
  3. is 
  4. select * from emp2 for update;  
  5. begin 
  6. for v_temp in c loop  
  7. if (v_temp.sal < 2000) then 
  8. update emp2 set sal = sal * 2 where current of c;   
  9. elsif (v_temp.sal = 5000) then 
  10. delete from emp2 where current of c;  
  11. end if;  
  12. end loop;  
  13. commit;  
  14. end

----創建存儲過程

  1. create or replace procedure p  
  2. is 
  3. cursor c is 
  4. select * from emp2 for update;  
  5. begin 
  6. for v_emp in c loop  
  7. if (v_emp.deptno = 10) then 
  8. update emp2 set sal = sal + 10 where current of c;  
  9. elsif (v_emp.deptno = 20) then 
  10. update emp2 set sal = sal + 20 where current of c;  
  11. else 
  12. update emp2 set sal = sal + 50 where current of c;  
  13. end if;  
  14. end loop;  
  15. commit;  
  16. end;   
  17. ---執行存儲過程  
  18. exec p;  
  19. ---或者  
  20. begin 
  21. p;  
  22. end

---帶參數的存儲過程

  1. create or replace procedure 
  2. max_num(v_a in number,v_b number,v_ret out number,v_temp in out number)  
  3. is 
  4. begin 
  5. if(v_a > v_b) then 
  6. v_ret := v_a;  
  7. else 
  8. v_ret := v_b;  
  9. end if;  
  10. v_temp := v_temp + 1;  
  11. end;  
  12. ---調用這個存儲過程  
  13. declare 
  14. v_a number :=3;  
  15. v_b number :=4;  
  16. v_ret number;  
  17. v_temp number :=5;  
  18. begin 
  19. max_num(v_a, v_b, v_ret, v_temp);  
  20. dbms_output.put_line(v_ret);  
  21. dbms_output.put_line(v_temp);  
  22. end

---函數

  1. create or replace function   
  2. sal_tax(v_sal number)  
  3. return number  
  4. is 
  5. begin 
  6. if (v_sal < 2000) then 
  7. return 0.10;  
  8. elsif (v_sal < 2750) then 
  9. return 0.15;  
  10. else 
  11. return 0.20;  
  12. end if;  
  13. end;   
  14. --調用這個函數(別的函數怎麼用,這個函數就怎麼用)  
  15. select ename,sal,sal_tax(sal) from emp; 

----觸發器

  1. --創建一個日志表  
  2. create table emp2_log  
  3. (  
  4. uname varchar2(20),  
  5. action varchar2(10),  
  6. atime date 
  7. );  
  8. --創建一個觸發器  
  9. create or replace trigger trig  
  10. after insert or delete or update on emp2 for each row  
  11. begin 
  12. if inserting then 
  13. insert into emp2_log values (user,'insert',sysdate);  
  14. elsif updating then 
  15. insert into emp2_log values (user,'update',sysdate);  
  16. elsif deleting then 
  17. insert into emp2_log values (user,'delete',sysdate);  
  18. end if;  
  19. end;  
  20. --調用這個觸發器  
  21. update emp2 set sal = sal*2 where deptno = 30; 

---更改有依賴關系的表的字段值的建立的一個觸發器

  1. create or replace trigger trip_change  
  2. after update on dept2  
  3. for each row  
  4. begin 
  5. update emp2 set deptno = :NEW.deptno where deptno = :OLD.deptno;  
  6. end;   
  7. ---觸發這個觸發器  
  8. update dept2 set deptno = 99 where deptno = 10; 

---樹狀結構的存儲與展示

  1. drop table article;  
  2. create table article  
  3. (  
  4. id number primary key,  
  5. cont varchar2(4000),  
  6. pid number,  
  7. isleaf number(1),--0 代表非葉子節點,1 代表葉子節點  
  8. alevel number(2)  
  9. );  
  10. insert into article values(1,'螞蟻大戰大象',0,0,0);  
  11. insert into article values(2,'螞蟻大戰大象',1,0,1);  
  12. insert into article values(3,'螞蟻大戰大象',2,1,2);  
  13. insert into article values(4,'螞蟻大戰大象',2,0,2);  
  14. insert into article values(5,'螞蟻大戰大象',4,1,3);  
  15. insert into article values(6,'螞蟻大戰大象',1,0,1);  
  16. insert into article values(7,'螞蟻大戰大象',6,1,2);  
  17. insert into article values(8,'螞蟻大戰大象',6,1,2);  
  18. insert into article values(9,'螞蟻大戰大象',2,0,2);  
  19. insert into article values(10,'螞蟻大戰大象',9,1,3);  
  20. commit

---用存儲過程展示樹狀結構(用遞歸的方式實現)

  1. create or replace procedure p_tree(v_pid article.pid%type, v_level binary_integer) is 
  2. cursor c is select * from article where pid = v_pid;  
  3. v_preStr varchar2(1024) :='';  
  4. begin 
  5. for i in 1..v_level loop  
  6. v_preStr := v_preStr || '****';  
  7. end loop;  
  8. for v_article in c loop  
  9. dbms_output.put_line(v_preStr || v_article.cont);  
  10. if(v_article.isleaf = 0) then 
  11. p_tree(v_article.id, v_level + 1);  
  12. end if;  
  13. end loop;  
  14. end;   
  15. --執行這個存儲過程  
  16. exec p_tree(0,0);   
  17. --SQL> exec p_tree(0,0);  
  18. --螞蟻大戰大象  
  19. --****螞蟻大戰大象  
  20. --********螞蟻大戰大象  
  21. --********螞蟻大戰大象  
  22. --************螞蟻大戰大象  
  23. --********螞蟻大戰大象  
  24. --************螞蟻大戰大象  
  25. --****螞蟻大戰大象  
  26. --********螞蟻大戰大象                        
  27. --********螞蟻大戰大象                        
  28. --PL/SQL 過程已成功完成。  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved