以下的文章,主要為大家在實際工作中提供一種解決方法。
---用戶名:scott
---密 碼:tiger
---*********Oracle表連接與子查詢示例************
---求部門中哪些人的薪水最高
- 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 deptno,avg_sal,grade 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);
---求部門平均的薪水等級
- select deptno,avg(grade) from
- (select deptno,ename,grade from emp join salgrade s on (emp.sal between s.losal and s.hisal)) t
- group by deptno;
---雇員中哪些人是經理人
- select ename from emp where empno in (select distinct mgr from emp);
---不用組函數,求薪水的最高值
- select sal from emp where sal not in
- (select distinct e1.sal from emp e1 join emp e2 on (e1.sal < e2.sal));
---用組函數,求薪水的最高值
- select max(sal) from emp;
---求平均薪水最高的部門的部門編號
- select deptno , avg_sal from
- (select avg(sal) avg_sal,deptno from emp group by deptno) t
- where avg_sal =
- (select max(avg_sal) from (select avg(sal) avg_sal,deptno from emp group by deptno) t);
----組函數嵌套的寫法
- select deptno , avg_sal from
- (select avg(sal) avg_sal,deptno from emp group by deptno) t
- where avg_sal =
- (select max(avg(sal)) from emp group by deptno);
---求平均薪水最高的部門的名稱
- select dname from dept
- where deptno =
- (
- select deptno from
- (select avg(sal) avg_sal,deptno from emp group by deptno) t
- where avg_sal =
- (select max(avg_sal) from (select avg(sal) avg_sal,deptno from emp group by deptno) t)
- );
---求平均薪水的等級最低的部門的部門名稱
- select avg(sal) avg_sal,deptno from emp group by deptno
--部門平均薪水
- select min(avg_sal) from
- (
- select avg(sal) avg_sal,deptno from emp group by deptno
- )
--平均工資的最小值
- select avg_sal,deptno from
- (select avg(sal) avg_sal,deptno from emp group by deptno) t
- where avg_sal =
- (
- select min(avg_sal) from
- (
- select avg(sal) avg_sal,deptno from emp group by deptno
- )
- )
--平均工資的最小值及部門編號
- select t.avg_sal,t.deptno,s.grade from
- (select avg(sal) avg_sal,deptno from emp group by deptno) t
- join salgrade s on (t.avg_sal between s.losal and s.hisal)
- where avg_sal =
- (
- select min(avg_sal) from
- (
- select avg(sal) avg_sal,deptno from emp group by deptno
- )
- )
--平均工資的最小值及部門編號和工資等級
- select d.dname,t.avg_sal,t.deptno,s.grade from
- (select avg(sal) avg_sal,deptno from emp group by deptno) t
- join salgrade s on (t.avg_sal between s.losal and s.hisal)
- join dept d on (t.deptno = d.deptno)
- where avg_sal =
- (
- select min(avg_sal) from
- (
- select avg(sal) avg_sal,deptno from emp group by deptno
- )
- )
--平均工資的最小值及部門編號和工資等級及部門名稱
----Another 按照題意的寫法
- select t1.deptno,t1.avg_sal,grade,d.dname from
- (
- select deptno,avg_sal,grade 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
- join dept d on (t1.deptno = d.deptno)
- where grade =
- (
- select min(grade) from
- (
- select deptno,avg_sal,grade 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/sys as sysdba;
--已連接。
- grant create table, create vIEw to scott;
--授權成功。
---創建視圖
- create vIEw v$_dept_avg_sal_info as
- select deptno,avg_sal,grade 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);
--視圖已建立。
---創建這個v$_dept_avg_sal_info視圖可以簡化上面那個查詢的重復代碼
- select t1.deptno,t1.avg_sal,grade,d.dname from
- v$_dept_avg_sal_info t1
- join dept d on (t1.deptno = d.deptno)
- where grade =
- (
- select min(grade) from
- v$_dept_avg_sal_info
- );
---求比普通員工的最高薪水還要高的經理的名稱
- select max(sal) from emp where empno not in
- (select distinct mgr from emp where mgr is not null);
--普通員工的最高薪水
- 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 distinct mgr from emp where mgr is not null)
- );
--普通員工的最高薪水還要高的經理的名稱
--- Oracle 聯機歸檔日志 備份方式
---求薪水最高的第6名到第10名雇員(rownum)
- 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;
---五種約束條件
- create table stu
- (
- id number(2),
- name varchar2(20) constraint stu_name_nn not null,--非空約束
- sex number(2),
- age number(3),
- sdate date,
- grade number(3) default 1,
- class number(3),
- email varchar2(50),
- constraint stu_name_email_uin unique(name,email)--唯一主鍵
- ) ;
- insert into stu(name,email) values('','[email protected]')
- --ORA-01400: 無法將 NULL 插入 ("SCOTT"."STU"."NAME")
- insert into stu(name,email) values('tianyuexing','[email protected]');
- insert into stu(name,email) values('tianyuexing','[email protected]');
- --ORA-00001: 違反唯一約束條件 (SCOTT.STU_NAME_EMAIL_UIN)
---PL/SQL 一個簡單的存儲過程 分為四塊1.聲明declare 2.begin 3.exception 4.end
- set serveroutput on;
- declare
- v_num number :=0;
- begin
- v_num :=2/v_num;
- dbms_output.put_line(v_num);
- exception
- when others then
- dbms_output.put_line('error');
- end;
---%type 變量聲明的好處。
- declare
- v_empno2 emp.empno%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) := 2999;
- v_empnos(1) := 2434;
- v_empnos(-1) := 8989;
- dbms_output.put_line(v_empnos(-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 := 20;
- v_temp.dname := 'tianyuexing';
- v_temp.loc := 'qhd';
- dbms_output.put_line(v_temp.dname || ' ' ||v_temp.loc);
- end;
---使用 %rowtype聲明record變量
- declare
- v_temp dept%rowtype;
- begin
- v_temp.deptno := 20;
- v_temp.dname := 'yuexingtian';
- v_temp.loc := 'qhd';
- dbms_output.put_line(v_temp.dname || ' ' ||v_temp.loc);
- end;
---SQL語句的運用
- declare
- v_ename emp.ename%type;
- v_sal emp.sal%type;
- begin
- select ename,sal into v_ename,v_sal from emp where empno = 7369;
- dbms_output.put_line(v_ename ||' '||v_sal);
- end;
- declare
- v_emp emp%rowtype;
- begin
- select * into v_emp from emp where empno = 7369;
- dbms_output.put_line(v_emp.ename);
- end;
- --insert 語句
- declare
- v_deptno dept.deptno%type := 50;
- v_dname dept.dname%type :='yuexingtian';
- v_loc dept.loc%type := '秦皇島';
- begin
- insert into dept2 values (v_deptno,v_dname,v_loc);
- commit;
- end;
---sql%rowcount 多少條記錄被影響
- declare
- v_deptno emp2.deptno%type := 10;
- v_count number;
- begin
- update emp2 set sal = sal/2 where deptno = v_deptno;
- dbms_output.put_line(sql%rowcount ||'條記錄被影響');
- end;
--create語句
- begin
- execute immediate 'create table T (nnn varchar2(20) default ''yuexingtian'')';
- end;
---if語句,取出7369的薪水,如果<1200,則輸出'low',如果<2000則輸出'middle',否則輸出'high'.
- 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');
- elsif(v_sal < 2000) then
- dbms_output.put_line('middle');
- else
- dbms_output.put_line('high');
- end if;
- end;
---循環 loop (相當於do while)
- declare
- i binary_integer := 1;
- begin
- loop
- dbms_output.put_line(i);
- i := i+1;
- exit when (i>=11);
- end loop;
- end;
- ---when ……loop (相當於while)
- declare
- j binary_integer := 1;
- begin
- while j<11 loop
- dbms_output.put_line(j);
- j := j+1;
- end loop;
- end;
- ---for ...in... loop
- 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 = 4444;
- exception
- when no_data_found then
- dbms_output.put_line('沒有數據');
- end;
---記錄數據庫錯誤信息的errorlog
- 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; --創建遞增序列
- --PL/SQL
- 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_errcode,v_errmsg,sysdate);
- commit;
- end;
- select to_char(errdate,'YYYY-MM-DD HH24:MI:ss') from errorlog; ---具體的出錯時間。
---游標
- declare
- cursor c is
- select * from emp;
- v_emp c%rowtype;
- begin
- open c;
- fetch c into v_emp;
- dbms_output.put_line(v_emp.ename);
- close c;
- end;
- ---游標,循環取出所有的記錄。
- declare
- cursor c is
- select * from emp;
- v_emp 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;
- ---游標while 循環
- declare
- cursor c is
- select * from emp;
- v_emp c%rowtype;
- begin
- open c;
- fetch c into v_emp;
- while (c%found) loop
- dbms_output.put_line(v_emp.ename);
- fetch c into v_emp;
- end loop;
- close c;
- end;
- ---for循環 不用聲明變量,不用open游標 不用close游標 不用fetch
- 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;
- 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 emp2 for update;
- begin
- for v_temp in c loop
- if (v_temp.sal < 2000) then
- update emp2 set sal = sal * 2 where current of c;
- elsif (v_temp.sal = 5000) then
- delete from emp2 where current of c;
- end if;
- end loop;
- commit;
- end;
----創建存儲過程
- create or replace procedure p
- is
- cursor c is
- select * from emp2 for update;
- begin
- for v_emp in c loop
- if (v_emp.deptno = 10) then
- update emp2 set sal = sal + 10 where current of c;
- elsif (v_emp.deptno = 20) then
- update emp2 set sal = sal + 20 where current of c;
- else
- update emp2 set sal = sal + 50 where current of c;
- end if;
- end loop;
- commit;
- end;
- ---執行存儲過程
- exec p;
- ---或者
- begin
- p;
- end;
---帶參數的存儲過程
- create or replace procedure
- max_num(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 number :=5;
- begin
- max_num(v_a, v_b, v_ret, v_temp);
- dbms_output.put_line(v_ret);
- dbms_output.put_line(v_temp);
- end;
---函數
- create or replace function
- sal_tax(v_sal number)
- return number
- is
- begin
- if (v_sal < 2000) then
- return 0.10;
- elsif (v_sal < 2750) then
- return 0.15;
- else
- return 0.20;
- end if;
- end;
- --調用這個函數(別的函數怎麼用,這個函數就怎麼用)
- select ename,sal,sal_tax(sal) from emp;
----觸發器
- --創建一個日志表
- create table emp2_log
- (
- uname varchar2(20),
- action varchar2(10),
- atime date
- );
- --創建一個觸發器
- create or replace trigger trig
- after insert or delete or update on emp2 for each row
- begin
- if inserting then
- insert into emp2_log values (user,'insert',sysdate);
- elsif updating then
- insert into emp2_log values (user,'update',sysdate);
- elsif deleting then
- insert into emp2_log values (user,'delete',sysdate);
- end if;
- end;
- --調用這個觸發器
- update emp2 set sal = sal*2 where deptno = 30;
---更改有依賴關系的表的字段值的建立的一個觸發器
- create or replace trigger trip_change
- after update on dept2
- for each row
- begin
- update emp2 set deptno = :NEW.deptno where deptno = :OLD.deptno;
- end;
- ---觸發這個觸發器
- update dept2 set deptno = 99 where deptno = 10;
---樹狀結構的存儲與展示
- drop table article;
- create table article
- (
- id number primary key,
- cont varchar2(4000),
- pid number,
- isleaf number(1),--0 代表非葉子節點,1 代表葉子節點
- alevel number(2)
- );
- insert into article values(1,'螞蟻大戰大象',0,0,0);
- insert into article values(2,'螞蟻大戰大象',1,0,1);
- insert into article values(3,'螞蟻大戰大象',2,1,2);
- insert into article values(4,'螞蟻大戰大象',2,0,2);
- insert into article values(5,'螞蟻大戰大象',4,1,3);
- insert into article values(6,'螞蟻大戰大象',1,0,1);
- insert into article values(7,'螞蟻大戰大象',6,1,2);
- insert into article values(8,'螞蟻大戰大象',6,1,2);
- insert into article values(9,'螞蟻大戰大象',2,0,2);
- insert into article values(10,'螞蟻大戰大象',9,1,3);
- commit;
---用存儲過程展示樹狀結構(用遞歸的方式實現)
- create or replace procedure p_tree(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_tree(v_article.id, v_level + 1);
- end if;
- end loop;
- end;
- --執行這個存儲過程
- exec p_tree(0,0);
- --SQL> exec p_tree(0,0);
- --螞蟻大戰大象
- --****螞蟻大戰大象
- --********螞蟻大戰大象
- --********螞蟻大戰大象
- --************螞蟻大戰大象
- --********螞蟻大戰大象
- --************螞蟻大戰大象
- --****螞蟻大戰大象
- --********螞蟻大戰大象
- --********螞蟻大戰大象
- --PL/SQL 過程已成功完成。