zoukankan      html  css  js  c++  java
  • oracle所有操作

    --等值连接
    --查询员工信息: 员工号 姓名 月薪 部门名称
    select p.deptno,p.ename,p.sal ,t.dname from emp p,dept t where p.deptno=t.deptno;
    --不等值连接
    --查询员工信息: 员工号 姓名 月薪 工资级别
    select e.deptno,e.ename,e.sal,s.grade from emp e,salgrade s where e.sal between s.losal and s.hisal;
    --外连接
    --按部门统计员工人数: 部门号 部门名称 人数
    select d.deptno,d.dname,count(d.deptno) from emp e,dept d where e.deptno=d.deptno group by d.deptno,d.dname;
    ---希望: 在最后的结果中,包含某些不成立的记录
    ---外连接:
    ---左外连接: 当where e.deptno=d.deptno不成立的时候,等号左边所代表的表 任然被包含
    ----写法: where e.deptno=d.deptno(+)

    select d.deptno,d.dname,count(e.deptno) from emp e,dept d where e.deptno=d.deptno(+) group by d.deptno,d.dname;
    ---右外连接: 当where e.deptno=d.deptno不成立的时候,等号右边所代表的表 任然被包含
    ---写法:where e.deptno(+)=d.deptno
    select d.deptno,d.dname,count(e.deptno) from emp e,dept d where e.deptno(+)=d.deptno group by d.deptno,d.dname;
    --自连接
    ---查询员工信息:***的老板是***
    --自连接:通过表的别名,将同一张表视为多张表
    select e.ename||'的老板是'||p.ename from emp e,emp p where e.mgr=p.empno;
    --层次查询
    select level,empno,ename,sal,mgr from emp connect by prior empno=mgr start with mgr is null order by 1;
    --查询工资比SCOTT高的员工信息
    select e.* from emp e where e.sal > (select sal from emp p where p.ename='SCOTT');
    注意的问题
    --- 1. 括号
    --- 2. 合理的书写风格
    --- 3. 可以主查询的where select from having后面放置子查询
    --- 4. 不可以在主查询的group by后面放置子查询
    --- 5. 强调from后面的子查询
    --- 6. 主查询和子查询可以不是同一张表,只要子查询返回的结果 主查询可以使用即可
    --- 7. 一般不在子查询使用order by,但在Top-N分析问题中 必须使用order by
    --- 8. 一般先执行子查询,再执行主查询;但相关子查询除外
    --- 9. 单行子查询只能使用单行操作符 多行子查询只能使用多行操作符
    --- 10. 子查询中null
    -- 3. 可以主查询的where select from having后面放置子查询
    select e.ename,e.deptno,(select job from emp where empno=7839) from emp e ;
    --5. 强调from后面的子查询
    --查询员工的姓名和薪水
    select e.ename,e.sal from emp e;
    select f.* from (select e.ename,e.sal ,e.sal*12 from emp e) f;
    --6. 主查询和子查询可以不是同一张表,只要子查询返回的结果 主查询可以使用即可
    --查询部门名称为SALES的员工信息
    select e.* from emp e where e.deptno =(select deptno from dept where dname='SALES');
    --优化5:理论上,尽量使用多表查询

    --in 在集合中
    --查询部门名称是SALES和ACCOUNTING的员工
    select * from emp where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');
    select e.* from emp e,dept d where e.deptno=d.deptno and (d.dname='SALES' or d.dname='ACCOUNTING');
    --any: 和集合中 任意一个值比较
    --查询工资比30号部门任意一个员工高的员工信息
    select e.* from emp e where e.sal> any (select sal from emp where deptno=30);
    select e.* from emp e where e.sal> (select min(sal) from emp where deptno=30);
    --all:和集合的所有值比较
    --查询工资比30号部门所有员工高的员工信息
    select e.* from emp e where e.sal> all (select sal from emp where deptno=30);
    select e.* from emp e where e.sal> (select max(sal) from emp where deptno=30);
    --多行子查询中null
    --查询不是老板的员工信息
    select e.* from emp e where e.empno in (select mgr from emp );
    select e.* from emp e where e.empno not in (select mgr from emp where mgr is not null );
    ---查询部门号是10和20的员工信息
    select * from emp e where e.deptno in (10,20);
    select empno,ename,job,sal from emp where deptno=10
    union
    select empno,ename,job,sal from emp where deptno=20;

    select deptno,job,sum(sal) from emp group by rollup(deptno,job);

    select deptno,job,sum(sal) from emp group by deptno,job
    union
    select deptno,to_char(null),sum(sal) from emp group by deptno
    union
    select to_number(null),to_char(null),sum(sal) from emp ;
    -----工资最高的前三名
    select rownum, t.ename,t.sal
    from
    (select ename,sal,row_number() over (order by sal desc) rn from emp) t
    where rn<=3;
    select * from (select * from emp order by sal desc) where rownum<=3;
    --第一题
    select * from (
    select rownum r,u.* from
    (select ename,deptno,sal from emp order by sal desc) u
    where rownum<=8) q where r>5
    --第二题
    select e.ename,e.sal,o.m from emp e,(select deptno, avg(sal) m from emp group by deptno) o where e.deptno=o.deptno and e.sal>o.m;
    select e.ename,e.sal,(select avg(sal) m from emp where deptno=e.deptno) avga from emp e where e.sal>(select avg(sal) from emp where deptno=e.deptno);
    --第三题
    --组函数 行转列 wm_concat
    select * from emp;
    select deptno,wm_concat(ename) from emp group by deptno;
    select count(*) ,sum(decode(to_char(hiredate,'RR'),'80',1,0)) "1980",sum(decode(to_char(hiredate,'RR'),'81',1,0)) "1981",sum(decode(to_char(hiredate,'RR'),'82',1,0)) "1982",sum(decode(to_char(hiredate,'RR'),'87',1,0)) "1987" from emp;
    ---管理员登录
    sqlplus sys/你的密码 as sysdba (密码认证)
    sqlplus / as sysdba (主机认证 优先)
    ---解锁
    alter user scott account unlock;
    ---改密码
    alter user scott identified by 新密码;
    ---SQL类型
    ---1. DML(Data Manipulation Lanuage 数据操作语言): select insert update delete
    ---2. DDL(Data Definition Language 数据定义语言): create/alter/drop/truncate table create/drop view/sequence/index/synonym
    ---3. DCL(Data Control Language 数据控制语言): commit rollback
    --插入数据 insert
    insert into emp (empno,ename,sal ,deptno) values(1001,'Tom',6000,20);
    --隐式/显式插入null
    -----地址符 &
    insert into emp (empno,ename,sal ,deptno) values(&empno,'&ename',&sal,&deptno);
    select empno,ename,deptno from &t;
    rollback;
    --批处理
    create table emp10 as select * from emp where 1=2;
    select * from emp10;
    --一次性从emp中 将所有10号部门的员工插入到emp10
    insert into emp10 select * from emp where deptno=10;
    --更新数据
    --删除数据
    ----delete 和truncate的区别
    ---1. delete逐条删除 truncate 先摧毁表 再重建
    ---2. **** delete 是DML(可以回滚),truncate是DDL(不可以回滚)
    ---3. delete不会释放空间 truncate会
    ---4. delete会产生碎片 truncate不会
    ---5. delete可以闪回,truncate不可以
    create table testdelete(tid number ,tname varchar2(20));
    CREATE SEQUENCE SI_EXTERNAL_SEQ --SI_EXTERNAL_SEQ要创建的sequence的名字
    INCREMENT BY 1 -- 每次加几个
    START WITH 1 -- 从1开始计数
    NOMAXVALUE -- 不设置最大值
    NOCYCLE -- 一直累加,不循环
    CACHE 10;
    insert into testdelete values(SI_EXTERNAL_SEQ.NEXTVAL,'aaa');
    commit;
    select * from testdelete;
    set timing on
    create table testdelete2 as select * from testdelete;
    ------保存点
    create table testsavepoint
    (tid number,tname varchar2(20));
    set feedback on
    insert into testsavepoint values(1,'Tom');
    insert into testsavepoint values(2,'Mary');
    savepoint a;
    insert into testsavepoint values(3,'Moke');
    select * from testsavepoint;
    rollback to savepoint a;
    commit;
    ---
    create table test1(
    tid number,
    tname varchar2(20),
    hirdate date default sysdate
    )
    insert into test1(tid,tname) values(1,'tom');
    select * from test1;
    --行地址
    select rowid,empno,ename,job from emp;
    --保存20号部门的员工
    create table emp20 as select * from emp where deptno=20;
    select * from emp20;
    --创建表: 员工号 姓名 月薪 年薪 部门名称
    create table empinfo as select e.empno,e.ename,e.sal,e.sal*12 niansal ,d.dname from dept d,emp e where d.deptno=e.deptno;
    select * from empinfo;
    --修改表: 追加新列 修改列 删除列 重名列
    select * from test1;
    alter table test1 add age2 number;
    alter table test1 modify age varchar2(40);
    alter table test1 drop column age;
    alter table test1 rename column tid to ttid;
    select * from tab;
    drop table test1;
    --Oracle的回收站
    select * from recyclebin;
    ---清空回收站
    purge recyclebin;
    --drop table test1 purge; --> 不经过回收站直接删除
    --注意: 管理员没有回收站
    --检查性约束
    create table student(
    sid number primary key,
    sname varchar2(40) not null,
    age number check (age>0),
    gender varchar2(4) check(gender in ('男','女'))
    )
    select * from student;
    insert into student(sid,sname,age,gender) values(2,'aaa',25,'a');
    commit;
    create table teacher(
    sid number constraint t_pk primary key,
    sname varchar2(40) constraint t_name not null,
    age number constraint t_age check (age>0),
    gender varchar2(4) constraint t_gender check(gender in ('男','女'))
    )
    insert into teacher(sid,sname,age,gender) values(2,'aaa',25,'a');
    ----Hello World
    set serveroutput on

    declare

    begin

    dbms_output.put_line('Hello World');
    end;
    /
    -----if语句
    set serveroutput on
    accept num prompt '请输入一个数字';
    declare
    pnum number :=&num;
    begin

    if pnum=1 then dbms_output.put_line('输入的值为1');
    elsif pnum=2 then dbms_output.put_line('输入的值为2');
    elsif pnum=3 then dbms_output.put_line('输入的值为3');
    else dbms_output.put_line('输入的值为其它');
    end if;
    end;
    /
    --带参数的光标
    --查询某个部门中员工的姓名
    set serveroutput on
    accept num prompt '请输入一个数字';
    declare
    cursor cemp(dmo number) is select ename from emp where deptno=dmo;
    pname emp.ename%type;
    pnum number :=&num;
    begin
    open cemp(pnum);
    loop
    fetch cemp into pname;
    exit when cemp%notfound;
    dbms_output.put_line(pname);
    end loop;
    close cemp;

    end;
    /
    -----涨工资 总裁1000 经理800 其他400
    set serveroutput on

    declare
    cursor cemp is select empno,empjob from emp;
    pempno emp.empno%type;
    pjob emp.empjob%type;

    begin
    open cemp;
    loop
    fetch cemp into pempno,pjob;
    exit when cemp%notfound;
    if pjob='PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;
    elsif pjob='MANAGER' then update emp set sal=sal+800 where empno=pempno;
    else update emp set sal=sal+400 where empno=pempno;
    end if;
    end loop;
    close cemp;
    commit;
    dbms_output.put_line('完成!');
    end;
    /
    select * from emp;

    -----使用游标查询员工姓名和工资,并打印
    /*
    1. 光标的属性
    %isopen: 是否打开
    %rowcount: 行数
    %notfound: 没有记录

    2. 默认允许一次打开300个光标(修改光标: 第四天 管理方案)
    SQL> show parameters cursor

    NAME TYPE VALUE
    ------------------------------------ ----------- -------
    cursor_sharing string EXACT
    cursor_space_for_time boolean FALSE
    open_cursors integer 300
    session_cached_cursors integer 20
    */
    show parameters cursor;

    set serveroutput on

    declare
    cursor cemp is select ename,sal from emp;
    pename emp.ename%type;
    psal emp.sal%type;
    begin
    open cemp;
    loop
    fetch cemp into pename,psal;
    exit when cemp%notfound;
    dbms_output.put_line(pename||'的薪水为'||psal);
    end loop;
    close cemp;
    end;
    /
    --------查询并打印7839的姓名和薪水
    --记录型变量 代表一行
    set serveroutput on

    declare

    rec emp%rowtype;
    begin
    select * into rec from emp where empno=7839;
    dbms_output.put_line(rec.empno||'aaaa'||rec.sal);
    end;
    /
    实例1:统计每年入职的员工个数。
    set serveroutput on

    declare
    cursor cemp is select to_char(hiredate,'RR') from emp;
    phiredate varchar2(4);
    count80 number :=0;
    count81 number :=0;
    count82 number :=0;
    count87 number :=0;
    begin
    open cemp;
    loop
    fetch cemp into phiredate;
    exit when cemp%notfound;
    if phiredate='80' then count80:=count80+1;
    elsif phiredate='81' then count81:=count81+1;
    elsif phiredate='82' then count82:=count82+1;
    else count87:=count87+1;
    end if;
    end loop;
    close cemp;
    dbms_output.put_line('total'||(count80+count81+count82+count87));
    dbms_output.put_line(count80);
    dbms_output.put_line(count81);
    dbms_output.put_line(count82);
    dbms_output.put_line(count87);
    end;
    /
    ---为员工长工资。从最低工资调起每人长10%,但工资总额不能超过5万元,
    ----请计算长工资的人数和长工资后的工资总额,并输出输出长工资人数及工资总额。
    set serveroutput on

    declare
    cursor cemp is select empno,sal from emp;
    pempno emp.empno%type;
    psal emp.sal%type;
    countEmp number :=0;
    salTotal number ;
    begin
    select sum(sal) into salTotal from emp;
    open cemp;
    loop
    exit when salTotal>200000;
    fetch cemp into pempno,psal;
    exit when cemp%notfound;

    update emp set sal=sal*1.1 where empno=pempno;

    countEmp :=countEmp+1;
    if salTotal+psal*0.1<200000 then salTotal :=salTotal+psal*0.1;
    else exit;
    end if;
    end loop;
    close cemp;
    commit;
    dbms_output.put_line('人数:'||countEmp||' 工资总额:'||salTotal);
    end;
    /
    -----用PL/SQL语言编写一程序,实现按部门分段(6000以上、(6000,3000)、3000元以下)
    ----统计各工资段的职工人数、以及各部门的工资总额(工资总额中不包括奖金)

    set serveroutput on

    declare
    cursor cdept is select deptno from dept;
    pdeptno dept.deptno%type;

    cursor cemp(dno number) is select sal from emp where deptno=dno;
    psal emp.sal%type;
    count1 number;count2 number;count3 number;
    salTotal number;
    begin
    open cdept;
    loop
    fetch cdept into pdeptno;
    exit when cdept%notfound;
    count1 :=0;count2 :=0;count3 :=0;
    select sum(sal) into salTotal from emp where deptno=pdeptno;
    open cemp(pdeptno);
    loop
    fetch cemp into psal;
    exit when cemp%notfound;
    if psal<3000 then count1 :=count1+1;
    elsif psal>3000 and psal<6000 then count2 :=count2+1;
    else count3 :=count3+1;
    end if;
    end loop;
    close cemp;
    insert into msg1 values(pdeptno,count1,count2,count3,nvl(salTotal,0));
    end loop;
    close cdept;
    commit;
    dbms_output.put_line('完成');
    end;
    /
    create table msg1(
    n1 number,
    n2 number,
    n3 number,
    n4 number,
    n5 number
    )
    select *  from msg1;
    -----被0除
    set serveroutput on

    declare
    pnum number;
    begin
    pnum :=1/0;

    exception
    when Zero_Divide then dbms_output.put_line('1:0不能做被除数');
    dbms_output.put_line('2:0不能做被除数');
    when Value_error then dbms_output.put_line('算术或转换错误');
    when others then dbms_output.put_line('其他例外');
    end;
    /
    ----循环
    set serveroutput on

    declare
    pnum number;
    begin
    pnum :=0;
    loop
    exit when pnum>10;
    dbms_output.put_line(pnum);
    pnum :=pnum+1;
    end loop;
    end;
    /
    -----查询并打印7839的姓名和薪水
    set serveroutput on

    declare
    pename emp.ename%type;
    psal emp.sal%type;
    begin
    select ename,sal into pename,psal from emp where empno=7839;
    dbms_output.put_line(pename||'的薪水是'||psal);
    end;
    /
    ------查询50号部门的员工
    set serveroutput on

    declare
    cursor cemp is select ename from emp where deptno=30;
    pename emp.ename%type;
    no_emp_found exception;
    begin
    open cemp;
    fetch cemp into pename;
    if cemp%notfound then
    raise no_emp_found;
    end if;


    close cemp;
    exception
    when no_emp_found then dbms_output.put_line('没有找到员工');
    when others then dbms_output.put_line('其他例外');
    end;
    /


    select * from emp;
    /*
    create [or replace] PROCEDURE 过程名(参数列表)
    AS
    PLSQL子程序体;
    查询并返回某个员工的姓名 月薪和职位

    思考: out参数太多???
    */
    create or replace procedure queryEmpInfo(
    eno in number,
    pename out varchar2,
    psal out number,
    pjob out varchar2
    )
    as
    begin
    select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
    end;
    /
    /*
    实施复杂的安全性检查

    禁止在非工作时间 往emp表中插入数据
    CREATE [or REPLACE] TRIGGER 触发器名
    {BEFORE | AFTER}
    {DELETE | INSERT | UPDATE [OF 列名]}
    ON 表名
    PLSQL 块

    周末:to_char(sysdate,'day') in ('星期六','星期日')
    上班前 下班后: to_number(to_char(sysdate,'hh24')) not between 9 and 18
    */
    create or replace trigger securityEmp
    before insert
    on emp
    begin
    if to_char(sysdate,'day') in ('星期三','星期六') or
    to_number(to_char(sysdate,'hh24')) not between 9 and 18 then
    raise_application_error(-20001,'不能在非工作时间插入数据');
    end if;
    end;
    /
    select * from emp;
    insert into emp(empno,ename,empjob,sal) values(100,'hhh','manager',8000);
    select * from user_source where name like '%SECURITYEMP%';
    drop trigger checksal;
    /*
    数据确认

    涨后的薪水不能少于涨前的薪水
    CREATE [or REPLACE] TRIGGER 触发器名
    {BEFORE | AFTER}
    {DELETE | INSERT | UPDATE [OF 列名]}
    ON 表名
    [FOR EACH ROW [WHEN(条件) ] ]
    PLSQL 块

    */
    create or replace trigger checksal
    before update
    on emp
    for each row
    begin
    if :new.sal<:old.sal then
    raise_application_error(-20002,'涨后的薪水不能少于涨前的薪水.涨前:'||:old.sal||' 涨后:'||:new.sal);
    end if;
    end;
    /
    update emp set sal=sal-100 where empno=7839;
    /*
    CREATE [OR REPLACE] FUNCTION 函数名(参数列表)
    RETURN 函数值类型
    AS
    PLSQL子程序体;

    查询某个员工的年收入

    */
    create or replace function queryEmpIncome(eno in number)
    return number
    as
    psal emp.sal%type;
    pcomm emp.comm%type;
    begin
    select sal,comm into psal,pcomm from emp where empno=eno;
    return psal*12+nvl(pcomm,0);
    end;
    /
    /*
    create [or replace] PROCEDURE 过程名(参数列表)
    AS
    PLSQL子程序体;

    为指定的员工涨100块钱 并打印涨前和涨后的薪水
    */
    create or replace procedure raiseSalary(
    eno in number
    )
    as
    psal emp.sal%type;
    begin
    select sal into psal from emp where empno=eno;
    update emp set sal=sal+100 where empno=eno;
    dbms_output.put_line('涨前:'||psal||' 涨后:'||(psal+100));
    end;
    /

    create or replace trigger sayNewEmp
    after insert on emp
    declare

    begin
    dbms_output.put_line('插入数据!');

    end;
    /
    delete from emp where empno=1000;
    select * from emp;
    select * from user_source where type='CURSOR';
    /*
    1.错误的删除了数据,并且已经提交
    2.错误的删除了表drop table
    3.如何获取表上的历史记录
    4.如何撤销已经提交的事务
    闪回的类型
    1.闪回表:将表返回到过去的一个时间上
    2.闪回删除:操作oracle的回收站
    3.闪回版本查询:表上的历史记录
    4.闪回事务查询:获取表上的一个UNDO_SQL
    5.闪回数据库:将数据库返回到过去的一个时间上
    6.闪回归档日志
    */
    ---查询没有提交的数据
    show parameter undo;
    ----设置闪回时间 scope的取值:memoery(本次回话) spfile(重启后生效) both()
    alter system set undo_retention=1200 scope=both;
    ---系统改变号SCN----6952590965600 6952590966674
    select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss:mm') 时间,
    timestamp_to_scn(sysdate) SCN
    from dual;
    ---闪回表
    create table flashback_table (fid number,fname varchar2(40));
    insert into flashback_table values(1,'tom');
    insert into flashback_table values(2,'marry');
    insert into flashback_table values(3,'mike');

    delete from flashback_table where fid=2;
    select * from flashback_table;
    ---启动行移动ALTER TABLE table_name ENABLE ROW MOVEMENT
    alter table flashback_table enable row movement;
    flashback table flashback_table to SCN 6952590966674;
    ---如何获取离操作最近的一个时间或者SCN?
    select * from tab;
    drop table EMP20 purge;
    ----闪回删除的表
    flashback table MSG1 to before drop rename to msg5 ;
    create table MSG1(mid number,mname varchar2(30));
    select * from msg4;
    show recyclebin;
    purge recyclebin;
    -------管理员没有回收站

    create table ggg(mid number,mname varchar2(30));
    insert into ggg values(1,'ssss');
    drop table ggg;
    select * from ggg;
    flashback table ggg to before drop ;
    flashback table ggg to before drop rename to msg5 ;
    select * from msg5;
    -----返回版本
    create table version_table(tid number,tname varchar2(30));
    insert into version_table values(1,'tom');
    insert into version_table values(2,'mary');
    insert into version_table values(3,'mike');
    update version_table set tname='mary123' where tid=2;
    select * from version_table;
    -----查询返回版本的语法
    select tid,tname,versions_operation,versions_starttime,versions_endtime,versions_xid from version_table versions between timestamp minvalue and maxvalue;
    ----闪回事务查询
    create table tracation_table(tid number,tname varchar2(30));

    insert into tracation_table values(1,'tom');
    insert into tracation_table values(2,'mary');

    insert into tracation_table values(3,'mike');
    update tracation_table set tname='dfdfd' where tid=2;


    select tid,tname,versions_operation,versions_starttime,versions_endtime,versions_xid from tracation_table versions between timestamp minvalue and maxvalue;
    select operation,undo_sql from flashback_transaction_query where xid='0B00080016DF0000';
    exp scott/tiger @10.4.237.4:1521:orcl file=f:/a.dmp log=f:/log.log tables=dept,emp

    --等值连接
    --查询员工信息: 员工号 姓名 月薪 部门名称
    select p.deptno,p.ename,p.sal ,t.dname from emp p,dept t where p.deptno=t.deptno;
    --不等值连接
    --查询员工信息: 员工号 姓名 月薪 工资级别
    select e.deptno,e.ename,e.sal,s.grade from emp e,salgrade s where e.sal between s.losal and s.hisal;
    --外连接
    --按部门统计员工人数: 部门号 部门名称 人数
    select d.deptno,d.dname,count(d.deptno) from emp e,dept d where e.deptno=d.deptno group by d.deptno,d.dname;
    ---希望: 在最后的结果中,包含某些不成立的记录
    ---外连接:
    ---左外连接: 当where e.deptno=d.deptno不成立的时候,等号左边所代表的表 任然被包含
    ----写法: where e.deptno=d.deptno(+)

    select d.deptno,d.dname,count(e.deptno) from emp e,dept d where e.deptno=d.deptno(+) group by d.deptno,d.dname;
    ---右外连接: 当where e.deptno=d.deptno不成立的时候,等号右边所代表的表 任然被包含
    ---写法:where e.deptno(+)=d.deptno
    select d.deptno,d.dname,count(e.deptno) from emp e,dept d where e.deptno(+)=d.deptno group by d.deptno,d.dname;
    --自连接
    ---查询员工信息:***的老板是***
    --自连接:通过表的别名,将同一张表视为多张表
    select e.ename||'的老板是'||p.ename from emp e,emp p where e.mgr=p.empno;
    --层次查询
    select level,empno,ename,sal,mgr from emp connect by prior empno=mgr start with mgr is null order by 1;
    --查询工资比SCOTT高的员工信息
    select e.* from emp e where e.sal > (select sal from emp p where p.ename='SCOTT');
    注意的问题
    --- 1. 括号
    --- 2. 合理的书写风格
    --- 3. 可以主查询的where select from having后面放置子查询
    --- 4. 不可以在主查询的group by后面放置子查询
    --- 5. 强调from后面的子查询
    --- 6. 主查询和子查询可以不是同一张表,只要子查询返回的结果 主查询可以使用即可
    --- 7. 一般不在子查询使用order by,但在Top-N分析问题中 必须使用order by
    --- 8. 一般先执行子查询,再执行主查询;但相关子查询除外
    --- 9. 单行子查询只能使用单行操作符 多行子查询只能使用多行操作符
    --- 10. 子查询中null
    -- 3. 可以主查询的where select from having后面放置子查询
    select e.ename,e.deptno,(select job from emp where empno=7839) from emp e ;
    --5. 强调from后面的子查询
    --查询员工的姓名和薪水
    select e.ename,e.sal from emp e;
    select f.* from (select e.ename,e.sal ,e.sal*12 from emp e) f;
    --6. 主查询和子查询可以不是同一张表,只要子查询返回的结果 主查询可以使用即可
    --查询部门名称为SALES的员工信息
    select e.* from emp e where e.deptno =(select deptno from dept where dname='SALES');
    --优化5:理论上,尽量使用多表查询

    --in 在集合中
    --查询部门名称是SALES和ACCOUNTING的员工
    select * from emp where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');
    select e.* from emp e,dept d where e.deptno=d.deptno and (d.dname='SALES' or d.dname='ACCOUNTING');
    --any: 和集合中 任意一个值比较
    --查询工资比30号部门任意一个员工高的员工信息
    select e.* from emp e where e.sal> any (select sal from emp where deptno=30);
    select e.* from emp e where e.sal> (select min(sal) from emp where deptno=30);
    --all:和集合的所有值比较
    --查询工资比30号部门所有员工高的员工信息
    select e.* from emp e where e.sal> all (select sal from emp where deptno=30);
    select e.* from emp e where e.sal> (select max(sal) from emp where deptno=30);
    --多行子查询中null
    --查询不是老板的员工信息
    select e.* from emp e where e.empno in (select mgr from emp );
    select e.* from emp e where e.empno not in (select mgr from emp where mgr is not null );
    ---查询部门号是10和20的员工信息
    select * from emp e where e.deptno in (10,20);
    select empno,ename,job,sal from emp where deptno=10
    union
    select empno,ename,job,sal from emp where deptno=20;

    select deptno,job,sum(sal) from emp group by rollup(deptno,job);

    select deptno,job,sum(sal) from emp group by deptno,job
    union
    select deptno,to_char(null),sum(sal) from emp group by deptno
    union
    select to_number(null),to_char(null),sum(sal) from emp ;
    -----工资最高的前三名
    select rownum, t.ename,t.sal
    from
    (select ename,sal,row_number() over (order by sal desc) rn from emp) t
    where rn<=3;
    select * from (select * from emp order by sal desc) where rownum<=3;
    --第一题
    select * from (
    select rownum r,u.* from
    (select ename,deptno,sal from emp order by sal desc) u
    where rownum<=8) q where r>5
    --第二题
    select e.ename,e.sal,o.m from emp e,(select deptno, avg(sal) m from emp group by deptno) o where e.deptno=o.deptno and e.sal>o.m;
    select e.ename,e.sal,(select avg(sal) m from emp where deptno=e.deptno) avga from emp e where e.sal>(select avg(sal) from emp where deptno=e.deptno);
    --第三题
    --组函数 行转列 wm_concat
    select * from emp;
    select deptno,wm_concat(ename) from emp group by deptno;
    select count(*) ,sum(decode(to_char(hiredate,'RR'),'80',1,0)) "1980",sum(decode(to_char(hiredate,'RR'),'81',1,0)) "1981",sum(decode(to_char(hiredate,'RR'),'82',1,0)) "1982",sum(decode(to_char(hiredate,'RR'),'87',1,0)) "1987" from emp;
    ---管理员登录
    sqlplus sys/你的密码 as sysdba (密码认证)
    sqlplus / as sysdba (主机认证 优先)
    ---解锁
    alter user scott account unlock;
    ---改密码
    alter user scott identified by 新密码;
    ---SQL类型
    ---1. DML(Data Manipulation Lanuage 数据操作语言): select insert update delete
    ---2. DDL(Data Definition Language 数据定义语言): create/alter/drop/truncate table create/drop view/sequence/index/synonym
    ---3. DCL(Data Control Language 数据控制语言): commit rollback
    --插入数据 insert
    insert into emp (empno,ename,sal ,deptno) values(1001,'Tom',6000,20);
    --隐式/显式插入null
    -----地址符 &
    insert into emp (empno,ename,sal ,deptno) values(&empno,'&ename',&sal,&deptno);
    select empno,ename,deptno from &t;
    rollback;
    --批处理
    create table emp10 as select * from emp where 1=2;
    select * from emp10;
    --一次性从emp中 将所有10号部门的员工插入到emp10
    insert into emp10 select * from emp where deptno=10;
    --更新数据
    --删除数据
    ----delete 和truncate的区别
    ---1. delete逐条删除 truncate 先摧毁表 再重建
    ---2. **** delete 是DML(可以回滚),truncate是DDL(不可以回滚)
    ---3. delete不会释放空间 truncate会
    ---4. delete会产生碎片 truncate不会
    ---5. delete可以闪回,truncate不可以
    create table testdelete(tid number ,tname varchar2(20));
    CREATE SEQUENCE SI_EXTERNAL_SEQ --SI_EXTERNAL_SEQ要创建的sequence的名字
    INCREMENT BY 1 -- 每次加几个
    START WITH 1 -- 从1开始计数
    NOMAXVALUE -- 不设置最大值
    NOCYCLE -- 一直累加,不循环
    CACHE 10;
    insert into testdelete values(SI_EXTERNAL_SEQ.NEXTVAL,'aaa');
    commit;
    select * from testdelete;
    set timing on
    create table testdelete2 as select * from testdelete;
    ------保存点
    create table testsavepoint
    (tid number,tname varchar2(20));
    set feedback on
    insert into testsavepoint values(1,'Tom');
    insert into testsavepoint values(2,'Mary');
    savepoint a;
    insert into testsavepoint values(3,'Moke');
    select * from testsavepoint;
    rollback to savepoint a;
    commit;
    ---
    create table test1(
    tid number,
    tname varchar2(20),
    hirdate date default sysdate
    )
    insert into test1(tid,tname) values(1,'tom');
    select * from test1;
    --行地址
    select rowid,empno,ename,job from emp;
    --保存20号部门的员工
    create table emp20 as select * from emp where deptno=20;
    select * from emp20;
    --创建表: 员工号 姓名 月薪 年薪 部门名称
    create table empinfo as select e.empno,e.ename,e.sal,e.sal*12 niansal ,d.dname from dept d,emp e where d.deptno=e.deptno;
    select * from empinfo;
    --修改表: 追加新列 修改列 删除列 重名列
    select * from test1;
    alter table test1 add age2 number;
    alter table test1 modify age varchar2(40);
    alter table test1 drop column age;
    alter table test1 rename column tid to ttid;
    select * from tab;
    drop table test1;
    --Oracle的回收站
    select * from recyclebin;
    ---清空回收站
    purge recyclebin;
    --drop table test1 purge; --> 不经过回收站直接删除
    --注意: 管理员没有回收站
    --检查性约束
    create table student(
    sid number primary key,
    sname varchar2(40) not null,
    age number check (age>0),
    gender varchar2(4) check(gender in ('男','女'))
    )
    select * from student;
    insert into student(sid,sname,age,gender) values(2,'aaa',25,'a');
    commit;
    create table teacher(
    sid number constraint t_pk primary key,
    sname varchar2(40) constraint t_name not null,
    age number constraint t_age check (age>0),
    gender varchar2(4) constraint t_gender check(gender in ('男','女'))
    )
    insert into teacher(sid,sname,age,gender) values(2,'aaa',25,'a');
    ----Hello World
    set serveroutput on

    declare

    begin

    dbms_output.put_line('Hello World');
    end;
    /
    -----if语句
    set serveroutput on
    accept num prompt '请输入一个数字';
    declare
    pnum number :=&num;
    begin

    if pnum=1 then dbms_output.put_line('输入的值为1');
    elsif pnum=2 then dbms_output.put_line('输入的值为2');
    elsif pnum=3 then dbms_output.put_line('输入的值为3');
    else dbms_output.put_line('输入的值为其它');
    end if;
    end;
    /
    --带参数的光标
    --查询某个部门中员工的姓名
    set serveroutput on
    accept num prompt '请输入一个数字';
    declare
    cursor cemp(dmo number) is select ename from emp where deptno=dmo;
    pname emp.ename%type;
    pnum number :=&num;
    begin
    open cemp(pnum);
    loop
    fetch cemp into pname;
    exit when cemp%notfound;
    dbms_output.put_line(pname);
    end loop;
    close cemp;

    end;
    /
    -----涨工资 总裁1000 经理800 其他400
    set serveroutput on

    declare
    cursor cemp is select empno,empjob from emp;
    pempno emp.empno%type;
    pjob emp.empjob%type;

    begin
    open cemp;
    loop
    fetch cemp into pempno,pjob;
    exit when cemp%notfound;
    if pjob='PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;
    elsif pjob='MANAGER' then update emp set sal=sal+800 where empno=pempno;
    else update emp set sal=sal+400 where empno=pempno;
    end if;
    end loop;
    close cemp;
    commit;
    dbms_output.put_line('完成!');
    end;
    /
    select * from emp;

    -----使用游标查询员工姓名和工资,并打印
    /*
    1. 光标的属性
    %isopen: 是否打开
    %rowcount: 行数
    %notfound: 没有记录

    2. 默认允许一次打开300个光标(修改光标: 第四天 管理方案)
    SQL> show parameters cursor

    NAME TYPE VALUE
    ------------------------------------ ----------- -------
    cursor_sharing string EXACT
    cursor_space_for_time boolean FALSE
    open_cursors integer 300
    session_cached_cursors integer 20
    */
    show parameters cursor;

    set serveroutput on

    declare
    cursor cemp is select ename,sal from emp;
    pename emp.ename%type;
    psal emp.sal%type;
    begin
    open cemp;
    loop
    fetch cemp into pename,psal;
    exit when cemp%notfound;
    dbms_output.put_line(pename||'的薪水为'||psal);
    end loop;
    close cemp;
    end;
    /
    --------查询并打印7839的姓名和薪水
    --记录型变量 代表一行
    set serveroutput on

    declare

    rec emp%rowtype;
    begin
    select * into rec from emp where empno=7839;
    dbms_output.put_line(rec.empno||'aaaa'||rec.sal);
    end;
    /
    实例1:统计每年入职的员工个数。
    set serveroutput on

    declare
    cursor cemp is select to_char(hiredate,'RR') from emp;
    phiredate varchar2(4);
    count80 number :=0;
    count81 number :=0;
    count82 number :=0;
    count87 number :=0;
    begin
    open cemp;
    loop
    fetch cemp into phiredate;
    exit when cemp%notfound;
    if phiredate='80' then count80:=count80+1;
    elsif phiredate='81' then count81:=count81+1;
    elsif phiredate='82' then count82:=count82+1;
    else count87:=count87+1;
    end if;
    end loop;
    close cemp;
    dbms_output.put_line('total'||(count80+count81+count82+count87));
    dbms_output.put_line(count80);
    dbms_output.put_line(count81);
    dbms_output.put_line(count82);
    dbms_output.put_line(count87);
    end;
    /
    ---为员工长工资。从最低工资调起每人长10%,但工资总额不能超过5万元,
    ----请计算长工资的人数和长工资后的工资总额,并输出输出长工资人数及工资总额。
    set serveroutput on

    declare
    cursor cemp is select empno,sal from emp;
    pempno emp.empno%type;
    psal emp.sal%type;
    countEmp number :=0;
    salTotal number ;
    begin
    select sum(sal) into salTotal from emp;
    open cemp;
    loop
    exit when salTotal>200000;
    fetch cemp into pempno,psal;
    exit when cemp%notfound;

    update emp set sal=sal*1.1 where empno=pempno;

    countEmp :=countEmp+1;
    if salTotal+psal*0.1<200000 then salTotal :=salTotal+psal*0.1;
    else exit;
    end if;
    end loop;
    close cemp;
    commit;
    dbms_output.put_line('人数:'||countEmp||' 工资总额:'||salTotal);
    end;
    /
    -----用PL/SQL语言编写一程序,实现按部门分段(6000以上、(6000,3000)、3000元以下)
    ----统计各工资段的职工人数、以及各部门的工资总额(工资总额中不包括奖金)

    set serveroutput on

    declare
    cursor cdept is select deptno from dept;
    pdeptno dept.deptno%type;

    cursor cemp(dno number) is select sal from emp where deptno=dno;
    psal emp.sal%type;
    count1 number;count2 number;count3 number;
    salTotal number;
    begin
    open cdept;
    loop
    fetch cdept into pdeptno;
    exit when cdept%notfound;
    count1 :=0;count2 :=0;count3 :=0;
    select sum(sal) into salTotal from emp where deptno=pdeptno;
    open cemp(pdeptno);
    loop
    fetch cemp into psal;
    exit when cemp%notfound;
    if psal<3000 then count1 :=count1+1;
    elsif psal>3000 and psal<6000 then count2 :=count2+1;
    else count3 :=count3+1;
    end if;
    end loop;
    close cemp;
    insert into msg1 values(pdeptno,count1,count2,count3,nvl(salTotal,0));
    end loop;
    close cdept;
    commit;
    dbms_output.put_line('完成');
    end;
    /
    create table msg1(
    n1 number,
    n2 number,
    n3 number,
    n4 number,
    n5 number
    )
    select *  from msg1;
    -----被0除
    set serveroutput on

    declare
    pnum number;
    begin
    pnum :=1/0;

    exception
    when Zero_Divide then dbms_output.put_line('1:0不能做被除数');
    dbms_output.put_line('2:0不能做被除数');
    when Value_error then dbms_output.put_line('算术或转换错误');
    when others then dbms_output.put_line('其他例外');
    end;
    /
    ----循环
    set serveroutput on

    declare
    pnum number;
    begin
    pnum :=0;
    loop
    exit when pnum>10;
    dbms_output.put_line(pnum);
    pnum :=pnum+1;
    end loop;
    end;
    /
    -----查询并打印7839的姓名和薪水
    set serveroutput on

    declare
    pename emp.ename%type;
    psal emp.sal%type;
    begin
    select ename,sal into pename,psal from emp where empno=7839;
    dbms_output.put_line(pename||'的薪水是'||psal);
    end;
    /
    ------查询50号部门的员工
    set serveroutput on

    declare
    cursor cemp is select ename from emp where deptno=30;
    pename emp.ename%type;
    no_emp_found exception;
    begin
    open cemp;
    fetch cemp into pename;
    if cemp%notfound then
    raise no_emp_found;
    end if;


    close cemp;
    exception
    when no_emp_found then dbms_output.put_line('没有找到员工');
    when others then dbms_output.put_line('其他例外');
    end;
    /


    select * from emp;
    /*
    create [or replace] PROCEDURE 过程名(参数列表)
    AS
    PLSQL子程序体;
    查询并返回某个员工的姓名 月薪和职位

    思考: out参数太多???
    */
    create or replace procedure queryEmpInfo(
    eno in number,
    pename out varchar2,
    psal out number,
    pjob out varchar2
    )
    as
    begin
    select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;
    end;
    /
    /*
    实施复杂的安全性检查

    禁止在非工作时间 往emp表中插入数据
    CREATE [or REPLACE] TRIGGER 触发器名
    {BEFORE | AFTER}
    {DELETE | INSERT | UPDATE [OF 列名]}
    ON 表名
    PLSQL 块

    周末:to_char(sysdate,'day') in ('星期六','星期日')
    上班前 下班后: to_number(to_char(sysdate,'hh24')) not between 9 and 18
    */
    create or replace trigger securityEmp
    before insert
    on emp
    begin
    if to_char(sysdate,'day') in ('星期三','星期六') or
    to_number(to_char(sysdate,'hh24')) not between 9 and 18 then
    raise_application_error(-20001,'不能在非工作时间插入数据');
    end if;
    end;
    /
    select * from emp;
    insert into emp(empno,ename,empjob,sal) values(100,'hhh','manager',8000);
    select * from user_source where name like '%SECURITYEMP%';
    drop trigger checksal;
    /*
    数据确认

    涨后的薪水不能少于涨前的薪水
    CREATE [or REPLACE] TRIGGER 触发器名
    {BEFORE | AFTER}
    {DELETE | INSERT | UPDATE [OF 列名]}
    ON 表名
    [FOR EACH ROW [WHEN(条件) ] ]
    PLSQL 块

    */
    create or replace trigger checksal
    before update
    on emp
    for each row
    begin
    if :new.sal<:old.sal then
    raise_application_error(-20002,'涨后的薪水不能少于涨前的薪水.涨前:'||:old.sal||' 涨后:'||:new.sal);
    end if;
    end;
    /
    update emp set sal=sal-100 where empno=7839;
    /*
    CREATE [OR REPLACE] FUNCTION 函数名(参数列表)
    RETURN 函数值类型
    AS
    PLSQL子程序体;

    查询某个员工的年收入

    */
    create or replace function queryEmpIncome(eno in number)
    return number
    as
    psal emp.sal%type;
    pcomm emp.comm%type;
    begin
    select sal,comm into psal,pcomm from emp where empno=eno;
    return psal*12+nvl(pcomm,0);
    end;
    /
    /*
    create [or replace] PROCEDURE 过程名(参数列表)
    AS
    PLSQL子程序体;

    为指定的员工涨100块钱 并打印涨前和涨后的薪水
    */
    create or replace procedure raiseSalary(
    eno in number
    )
    as
    psal emp.sal%type;
    begin
    select sal into psal from emp where empno=eno;
    update emp set sal=sal+100 where empno=eno;
    dbms_output.put_line('涨前:'||psal||' 涨后:'||(psal+100));
    end;
    /

    create or replace trigger sayNewEmp
    after insert on emp
    declare

    begin
    dbms_output.put_line('插入数据!');

    end;
    /
    delete from emp where empno=1000;
    select * from emp;
    select * from user_source where type='CURSOR';
    /*
    1.错误的删除了数据,并且已经提交
    2.错误的删除了表drop table
    3.如何获取表上的历史记录
    4.如何撤销已经提交的事务
    闪回的类型
    1.闪回表:将表返回到过去的一个时间上
    2.闪回删除:操作oracle的回收站
    3.闪回版本查询:表上的历史记录
    4.闪回事务查询:获取表上的一个UNDO_SQL
    5.闪回数据库:将数据库返回到过去的一个时间上
    6.闪回归档日志
    */
    ---查询没有提交的数据
    show parameter undo;
    ----设置闪回时间 scope的取值:memoery(本次回话) spfile(重启后生效) both()
    alter system set undo_retention=1200 scope=both;
    ---系统改变号SCN----6952590965600 6952590966674
    select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss:mm') 时间,
    timestamp_to_scn(sysdate) SCN
    from dual;
    ---闪回表
    create table flashback_table (fid number,fname varchar2(40));
    insert into flashback_table values(1,'tom');
    insert into flashback_table values(2,'marry');
    insert into flashback_table values(3,'mike');

    delete from flashback_table where fid=2;
    select * from flashback_table;
    ---启动行移动ALTER TABLE table_name ENABLE ROW MOVEMENT
    alter table flashback_table enable row movement;
    flashback table flashback_table to SCN 6952590966674;
    ---如何获取离操作最近的一个时间或者SCN?
    select * from tab;
    drop table EMP20 purge;
    ----闪回删除的表
    flashback table MSG1 to before drop rename to msg5 ;
    create table MSG1(mid number,mname varchar2(30));
    select * from msg4;
    show recyclebin;
    purge recyclebin;
    -------管理员没有回收站

    create table ggg(mid number,mname varchar2(30));
    insert into ggg values(1,'ssss');
    drop table ggg;
    select * from ggg;
    flashback table ggg to before drop ;
    flashback table ggg to before drop rename to msg5 ;
    select * from msg5;
    -----返回版本
    create table version_table(tid number,tname varchar2(30));
    insert into version_table values(1,'tom');
    insert into version_table values(2,'mary');
    insert into version_table values(3,'mike');
    update version_table set tname='mary123' where tid=2;
    select * from version_table;
    -----查询返回版本的语法
    select tid,tname,versions_operation,versions_starttime,versions_endtime,versions_xid from version_table versions between timestamp minvalue and maxvalue;
    ----闪回事务查询
    create table tracation_table(tid number,tname varchar2(30));

    insert into tracation_table values(1,'tom');
    insert into tracation_table values(2,'mary');

    insert into tracation_table values(3,'mike');
    update tracation_table set tname='dfdfd' where tid=2;


    select tid,tname,versions_operation,versions_starttime,versions_endtime,versions_xid from tracation_table versions between timestamp minvalue and maxvalue;
    select operation,undo_sql from flashback_transaction_query where xid='0B00080016DF0000';
    exp scott/tiger @10.4.237.4:1521:orcl file=f:/a.dmp log=f:/log.log tables=dept,emp

  • 相关阅读:
    变量的创建和初始化
    HDU 1114 Piggy-Bank (dp)
    HDU 1421 搬寝室 (dp)
    HDU 2059 龟兔赛跑 (dp)
    HDU 2571 命运 (dp)
    HDU 1574 RP问题 (dp)
    HDU 2577 How to Type (字符串处理)
    HDU 1422 重温世界杯 (dp)
    HDU 2191 珍惜现在,感恩生活 (dp)
    HH实习 acm算法部 1689
  • 原文地址:https://www.cnblogs.com/zszitman/p/4668300.html
Copyright © 2011-2022 走看看