十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
以下的文章,主要为大家在实际工作中提供一种解决方法。

---用户名: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('','tianyuexing@163.com')
 - --ORA-01400: 无法将 NULL 插入 ("SCOTT"."STU"."NAME")
 - insert into stu(name,email) values('tianyuexing','tianyuexing@163.com');
 - insert into stu(name,email) values('tianyuexing','tianyuexing@163.com');
 - --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 过程已成功完成。
 
【编辑推荐】