zoukankan      html  css  js  c++  java
  • python | SQL语句总结(视图,序列,存储过程,函数,游标)



    SQL语句总结:
         创建用户:   create user scott identified(确认) by root;
         删除用户;    drop user  scott cascade(串联);
         创建角色:    create role myrole;
         授予权限:  grant  connect, resource to scott;    grant connect,resource to myrole; grant myrole to scott;
         移除权限:  revoke  connect  from scott;   revoke  myrole from scott;
         修改用户密码:   alter user scott identified by root;
         切换用户        conn  ntt/root;
        
        
         创建表 create table emp
              (     empno number(4),
                    ename varchar2(20),
                    job varchar2(20),      
                    sal number(7,2),
                    mgr number(4),
                    hiredate date,
                    deptno number(2)
                      );

           创建主键:一.     
           create table emp
         (empno number(4) primary key,
           ename varchar2(20),
           job varchar2(20),      
           sal number(7,2),
           mgr number(4),
           hiredate date,
           deptno number(2)
         );


         二. 
         create table emp
         (empno number(4) constraint pk primary key,
           ename varchar2(20),
           job varchar2(20),      
           sal number(7,2),
           mgr number(4),
           hiredate date,
           deptno number(2)
         );
         三.
           create table emp
         (empno number(4),
           ename varchar2(20),
           job varchar2(20),      
           sal number(7,2),
           mgr number(4),
           hiredate date,
           deptno number(2),
           constraint pk primary key(empno)
         );
         四.
           create table emp5
         (empno number(4),
           ename varchar2(20),
           job varchar2(20),      
           sal number(7,2),
           mgr number(4),
           hiredate date,
           deptno number(2)
         );
              alter table emp5 add primary key (empno);


          创建外键:
            一.
               create table emp
         (empno number(4) constraint pk primary key,
           ename varchar2(20),
           job varchar2(20),      
           sal number(7,2),
           mgr number(4),
           hiredate date,
           deptno number(2)    references dept(deptno)
         );
         二.
          create table emp
         (empno number(4) constraint pk primary key,
           ename varchar2(20),
           job varchar2(20),      
           sal number(7,2),
           mgr number(4),
           hiredate date,
           deptno number(2),
           foreign key (deptno)
           references dept(deptno)

         );
         三.
         create table emp
         (empno number(4) constraint pk primary key,
           ename varchar2(20),
           job varchar2(20),      
           sal number(7,2),
           mgr number(4),
           hiredate date,
           deptno number(2)
         );
         alter table emp add foreign key(deptno)
         references dept(deptno);
            删除表结构:
         drop table emp;
         修改表中的字段类型:
             alter table emp modify  empno number (10);
         修改表名:
         rename table emp to emp1;
         查看表结构:
              desc emp;
         添加字段:
            alter table emp add comm number(6,2;
         删除字段:
            alter table emp  drop column comm;

            表数据操作:
               insert的使用

              insert into emp values(
           添加全部
           1000,'ntt','clerk',4000,null,'1-1月-2015',null   
          
           );
             添加部分:
           insert into emp(empno,ename)valeus(
                   1000,'ntt'
           );
              拷贝一张表 (拷贝表结构和数据)

           create table empcopy
           as select * from emp;

           oracle 对DML 操作不是自动提交
              需要提交操作
              提交:commit;
              取消: rollback

              delete的使用:
           delete from 表名;
           delete from 表名 where 主键字段=值;
           delete from  emp where empno=1002;

           UPdate的使用:
           update 表名 set 字段名=值;
           update 表名 set 字段名=值 where 条件;
           update emp set ename='藏东'where empno =1001;
              update emp set sal=1000,hiredate ='1-1月-2015' where empno=1002;

             查询 SElect的使用:
         基本查询:
            select 字段1,字段2..... from 表名;
             条件查询:
             select from 表名 where ...
             使用的运算符:
             = !=(<>) < <= > >=
              需求:查询10号部门中的员工
                 select * from emp where deptno=10;
              需求:查询不在10号部门中的员工
             select * from emp where deptno !=10;
             select *from emp where deptno <> 10;
             ** 使用 is null或 is not null
             
                需求:  查询奖金为null的员工
                select * from emp where comm is null;
                 需求:  查询奖金不为null的员工
             select * from emp where comm is not null;
           ** 布尔连接:  and(逻辑与)    or(逻辑或)
           
    需求: 显示职位是clerk 没有奖
    金的员工
        select * from  emp where job='clerk' and comm is not null;

    需求: 显示职位是clerk 或没有奖
    金的员工
       select *from emp where job='cleck' or comm is not null;
             模糊查询:like
              通配符:
                        %:任意位数任意字符
                  _: 一位任意字符
         需求:显示名字中有’A‘的员工    
        
         select * from emp where ename like '%A%';

              需求:显示名字中首字母’A‘的员工
            select * from emp where ename like 'A%';
           需求:显示名字中第二个字母为’A‘的员工
           select * from emp where ename like '_A%';
        
                  区间:   between...and ..
                           not     between ...and..
         
         需求: 显示工资在800到1500 的员工
         select * from enp where sal between 800 and 1500;

         需求: 显示工资不在800到1500 的员工
        select * from emp where sal not between 800  and 1500;
       
                 **  范围:in    not in
           需求:显示普通员工和销售人员的信息

           select * from emp where job in('CLERK','SALESMAN');
          
         **排序查询:   order by desc  (降序)  asc(升序)  默认为升序
        
         查询员工名 工资 入职日期 根据工资降序来排
         select ename ,sal,hiredate from emp order by sal desc;
         查询员工名 工资 入职日期 根据工资降序来排 入职日期升序来排
         select ename,sal,hiredate from emp order by sal desc , hiredate asc;
         升序:
                     * number类型  比较值
                     *date 类型 时间晚 值越大
                     *字符类型 根据字母 排序
              查询 20 30号部门的员工 按照员工的奖金降序排序
           select * from from emp where deptno in(20,30) order by comm desc;
           nvl() 函数: 可把null变为0 用于比较排序
           ** null在,默认在排序中 最大
           select * from from emp where deptno in(20,30) order by nvl(comm,0) desc;

           查询中计算:
                查询员工姓名  工资 工资涨500后大于2000的结果:
             select ename , sal, (sal+500) newsal from emp where newsal>2000;

                查询员工名 工资 奖金 及员工的年薪
             select ename, sal, comm, (sal+nvl(comm,0))*12  yearsal from emp ;
             **null值和其他任何数据运算都为null;

                 单行函数:
              字符函数:
              lower() 大写转小写
              upper ()  小写转大写
              initcap() 首字母大写
              查询 职位是clerk的员工名, 员工职位,工资
              select  ename , job,sal from emp where lower(job)='clerk';
              select ename,job,sal from emp where upper(job) ='CLERK';
              select ename ,job,sal from emp where initcap(job)='Clerk';
               字符连接: ||
                  查询员工名, 工资 工资涨3倍后的结果
                  按照如下格式:
                    xiaoqiang sal is 300, hope 900;
                
                  select ename ||'sal is'  ||sal||', hope'||sal*3 hopesal from emp;
            length()  长度      length('dsadsads')


            concat()  字符连接   concat('hhhh',';')
            substr()   截子串    substr('sahghd',2,3) 2位位置 3为个数
            instr()     是否在串中   instr('sadd','d')
            trim()  去空格            trim('   dashg  ')
            replace()   替换       replace('dsadsad','d','f')

            数学函数:
            mod()  求模

            round()  四舍五入

            trunc() 截取

            日期函数:
              stsdate :系统时间

             months_between(): 
             select round(months_between(sysdate,'2-1月-2016')) from dual;

             add_months()
             select add(sysdate,3) from dual;

             last_day()
             select last_day(sysdate) from dual;

             next_day() 下一个星期几是几号
             select next_day(sysdate,'星期日') from dual;


               计算员工工作的月数, 天数 周数
            select round(MOnths_between (sysdate
         ,hiredate)) months,
           round((sysdate-hiredate)/7) weeks,
           Round(sysdate-hiredate) days from dual;
            oracle中使用双引号 ---起别名

         转换函数:
         数据类型的转换(隐式)自动转换
         select 5 || '5' from dual;   55
         select 5+'5' from dual;   10

    日期  to_date()<-------》to_char() 字符to_char  <—----—》to_number()  数字

      查询员工7369的员工名 入职日期  格式为(2015-1-1)
      select ename, to_char(hiredate,'yyyy-mm-dd') from emp where empno=7369;
      select ename,to_char(hiredate,'yyyy-mm--dd hh:mi:ss') from emp where empno =7369;
           数字转字符: 常用于数字转为货币表示
           9: 表示任意一位
           L:表示本地货币的符号
           $:表示美元符号

           select to_char(sal,'L999,999,999.99') from emp;

           分组查询:
           group by  组(聚合) 函数
           count() max() min() avg() sum()
           having: 筛选条件应用分组之后的运算结果
            查询每个部门员工的工资总和
         select sum(sal) from emp group by deptno;
         查询每个部门员工的最高工资
         select max(sal) from emp group by deptno;
         查询每个部门员工的最低工资
         select min(sal) from emp group by deptno;
         查询每个部门员工数

         select count(*) from  emp group by deptno;
       注意:分组查询中 ,只能查询分组字段和组函数的运算的结果
     
             需求: 查询10 20 号部门的平均工资

       select deptno,round(avg(sal))  from emp where deptno in(10,20) group by deptno;

        需求: 查询10 20 30号部门的平均工资, 降序排序
        select deptno ,round(avg(sal)) from emp where deptno in(10,20,30) group by deptno order by round(avg(sal)) desc;
          需求: 查询10 20 30号部门的平均工资, 降序排序 只保留平均工资大于2000的部门号和平均工资
        select deptno ,round(avg(sal)) from emp where deptno in (10,20,30) group by deptno having round(avg(sal)) >2000 order by ronud(avg(sal)) desc;
       查询emp表中有那些职位
       select job from emp group by job;
       或  select  distinct(别具一格) job from emp ;
        查询 emp表中 每种职位有都少员工
        select job, count(*) from emp group by job;
         查询 emp表中 每个部门的每种职位的工资总和
        select deptno,job ,sum(sal) from emp group by deptno ,job;
      数据的对应关系:
         一对多
         联合查询(多表查询):
         需求: 查询所有部门的员工名  工资 部门名 部门地址
         select ename,sal,dname,loc from emp , dept;(笛卡尔积现象) : 连接条件不明确
        
        (等值查询)select ename,sal,dname,loc from emp e,dept d where e.deptno=d.deptno;

        内连接查询 :查询所有的记录都满足连接条件
        (内连接): select ename,sal,dname,loc from emp e inner join dept d on e.deptno=d.deptno;

        外连接查询: 可以查询出不满足条件的数据
        左外连接: 查询出左表中满足和不满足连接条件的数据
       (左外连接)select ename,sal,dname,loc from emp e left join dept d on e.deptno=d.deptno;
        在oracle中左外连接还可以这样:
          select ename,sal,dname,loc from emp e,dept d where e.deptno=d.deptno(+);
         右外连接:查询出右表中满足和不满足连接条件的数据
         (右外连接) select ename,sal,dname, loc from  dept d right join  emp e on d.deptno=e.deptno;

        在oracle中右外连接还可以这样:
          select ename,sal,dname,loc from dept d,emp e where d.deptno(+)=e.deptno;

          全外连接:
          select ename,sal,dname,loc from emp e full join dept d on e.deptno=d.deptno;

        多对多对应关系:需要中间表
        查询所有用户名和用户的角色名
         select uname,rname from t_user,t_role,t_user_role where
             t_user.tid=t_user_role.tid and t_role.rid=t_user_role.rid;


        查询用户王航的角色
     
      select uname,rname from t_user,t_role,t_user_role where
           t_user.tid=1001  t_user.tid=t_user_role.tid and t_role.rid=t_user_role.rid;

        免去用户陆川的管理员角色
        delete from t_user_role where tid=1002 and rid=10;

        子查询:
         应用场景:
          1.在where子句中使用
          2.在from子句中使用
          select * from (select * from emp);
          3.在DML语句中可以使用
          例:
          修改员工smith的同部门SAl +200

        update emp set sal=sal+200 where deptno=(  select deptno from emp where lower(ename)='smith') and ename<>'SMITH';

          删除员工smith的部门员工信息

          delete from emp where deptno=(select deptno from emp where ename='SMITH');
        
         普通子查询:

         子查询可以独立执行  先执行子查询 再执行主查询
         查询员工smith的同部门同事信息
         select * from emp where deptno=(select deptno from emp where lower(ename)='smith') and ename<> 'SMITH';

         相关子查询:
         子查询的查询结果与主查询相关


         查询 工资比本部门平均工资高的员工名 工资,部门
           select ename,sal, deptno from emp e where sal>(select round(avg(sal)) from emp where deptno=e.deptno );
         查询工资低于同职位同事平均工资的员工信息

          select * from emp  e where sal<(select round(avg(sal)) from emp where job=e.job);

         **in   **not in   表示范围

    select * from emp where deptno in(select deptno from emp where job='ANALYST' or job='PRESIDENT');
         **exists  ** not exists

    需求: 查询有部下的员工
       select empno,ename,job,mgr from emp e where exists(select * from emp where mgr=e.empno);

     

    需求: 查询没有部下的员工
            select empno,ename,job,mgr from emp e where not exists(select * from emp where mgr=e.empno);     
           ************分页查询*************
           rownum : 伪列 行号

           一.   page=2
                pageSize=3

                start: (page-1)*pageSize+1
                end: page*pageSize

         二.
             select * from (
              select rownum rn ,d.*
              from  (select * from emp) d
              where rownum<=end
              ) where rn>=start;

       

             三.  分页查询中需要计算最大页数
         totalRecord   : 总记录数

         pageSize: 每页记录数(约定好)

         maxpage=totalRecord%pageSize=0?totalRecord/pageSize:(totalRecord/pageSize)+1;

        ***********************************************************************************
                查询比smith薪水都高的员工信息
              (smith可能有多个)
              注意:子查询中,使用关系运算符 子查询不可以
    返回多个行
            select * from emp where sal> all(select sal from emp where ename ='SMITH');

              查询部门SALES包含哪些职位
             select  distinct job from  emp where deptno =(
         select deptno from dept where  dname='SALES'
         );


              查询比SALES部门所有员工薪水高的员工信息
               select *from emp where sal>  all(   select sal from emp where deptno=(select deptno from dept where dname='SALES'));

           查询比reseARch 部门任意员工薪水高的员工信息
             select * from emp where sal> any  (select sal from emp where deptno =(
            select deptno from dept where dname='RESEARCH'));

          
              查询BLAKE的下属信息
               select * from emp where mgr in(
               select empno from emp where ename='BLAKE'
            );

           查询每个部门拿最高薪水的员工信息
         select * from emp where (deptno,sal) in(  select deptno ,max(sal) from emp  group by deptno);


           查询比10号部门员工多的部门
            select count(*) from emp  group by deptno having count(*)>( select count(*) from emp where deptno=10);


           查询没有员工的部门
          
           select * from dept d where not exists (
             select 1 from emp where deptno=d.deptno
           );

              查询有员工的部门
            select * from dept d where  exists (
             select 1 from emp where deptno=d.deptno
           );

            集合的操作:

         union  (去重)
         union all(不去重)

            交集
         intersect 

         差集
         minus

         oracle 中其他的对象
         sequence  (序列)
         view (视图)
         index(索引)

         sequence :
            create sequence seq01_1507
            start with 1000   --初始值
            increment by 10  --自增
            maxvalue 10000  ---最大值
            cache 20  ;  --缓存中值的个数

          使用sequence:
             nextval  currval

         使用sequence值数据添加
         * 创建一个sequence
         * emp 中添加数据 员工编号使用序列的值
           create sequence seq_emp
           start with 8000
           increment by 10;
           insert into emp(empno,ename) values (
              seq_emp.nextval,'桑达'
           );

           view视图
           命名的查询,视图中并非存在数据
           可以把视图看做一个虚拟的表
           可以简化查询
           可以隐藏 表结构

           create or replace view emp_view
           as
           select * from emp;
           视图中关联的表称为视图的基表

           创建视图需要给用户授权
           grant create any view to scott;

           使用视图
           select * from emp_view;
           使用多基表 创建视图
           create or replace view emp_dept
           as
           select ename,sal,job,dname,loc from emp e left join dept d on e.deptno=d.deptno;

           通过视图执行DML的操作

           insert into emp_view(empno,ename)
              values(1001,'三灯') ;
          
         update emp_view set ename='僧淡'
         where empno='1001';

         delect from emp_view where empno=1001;

         通过视图实现对数据的增删改  只能是单基表视图
         多基表视图  不建议执行数据的更新操作
         
          独立实现    创建视图  查询emp表和dept表
            查询员工标号  姓名 薪水 职位 入职日期  部门号 部门名  部门地址  并按入职地址排序;
       
            create or replace view emp_dept
         as
         select * from(
         select rownum rn, ed.*   from
            (select empno,ename,sal,job,hiredate,e.deptno dname
                    from emp e left join dept d on e.deptno=d.deptno order by hiredate asc) ed
                 where rownum<=10 )
                 where rn>=5;

           oracle 中的表分为数据表* 数据字典
           常见数据字典:
           user_tables
           user_views
           user_constraints
           user_sequences
           user_indexes
           all_tables 用户可以访问的所有的表
           all_views
           all_constraints
           all_sequences

           查询emp表中的约束
           select constraint_name from user_constraints
           where table_name='EMP';
           查询视图名
           select view_name from user_views;

           查询视图中相关联的sql语句
           select text from uaer_views
           where view_name='EMP_VIEW';

           查询用户中所有的序列
           select * from user_sequences;

           索引 :index
           提高oracle 表中数据查询速度
           oracle中主字段自动加索引
           unique(唯一)字段自动加索引

           添加索引
                create index emp_ename_index
             on emp (ename);

            select index_name from user_indexes where table_name='EMP';

            独立实现:  索引性能测试
                     拷贝emp表  emp_copy_1507
                  create table emp_copy_1507 as select * from emp;
                        
                  反复复制emp_copy_1507的数据到本表
                  insert into emp_copy_1507 select * from emp_copy_1507;
                
                  修改表emp——copy-1507 中empnode 类型 number(7);
                 alter table emp_copy_1507 modify empno number(7);
                 
                  修改表    中empno字段的值为rownum
                  update emp_copy_1507 set empno=rownum;

                  查询第500000条记录 记录操作时间
                        select * from emp_copy_1507 where empno=500000;

                  创建索引  empno
                  create index emp_copy_1507 on emp_copy_1507(empno);

                  查询第500000条记录 记录操作时间
           
                  
                 PL/SQL  (Oracle):
               procedure Language/
              Structured Query Language
                     编程语言+SQL
            
                 PL/SQL 最基本的可以独立执行的程序单元为语句块

              PL/SQL 中分为不同种的程序
              分别为:  匿名语句块
                       **存储过程**
                    函数
                    触发器

                  declare
               begin
               dbms_output.put_line('hello');
               end;

               变量的定义与赋值
               declare
                   v_age number(2);
               begin
                   v_age:=33;
                dbms_output.put_line(v_age);
               end;

               注:在赋值时使用 :=  
                 
               分支语句:

               if语句
               declare
                   v_num number(2);
                v_char varchar2(1);
               begin
               v_num :=2;
               if v_num=1 then
               v_char :='A';
               elsif  v_num=2 then
               v_char :='B';
               elsif v_num=3 then
               v_char :='c';
               else
               v_char :='o';
               end if;
               dbms_output.put_line(v_char);

               end;

           case结构语句

           declare
              v_num number(2);
              v_char varchar2(10);
              begin
              v_num :=2;
              case
              when v_num=1 then v_char:='aa';
              when v_num=2  then v_char :='aaa';
              when v_num=3 then v_char :='SSSS';
              when v_num=4 then v_char :='sdd';
              else
              v_char :='0';
              end case;
                dbms_output.put_line(v_char);
              end;
                循环语句:
             loop循环 if退出
             declare
             v_sum number(6);
             v_i   number(3);
             begin
             v_sum :=0;
             v_i := 1;
             loop
                 if v_i=101 then
              exit;
              end if;
              v_sum := v_sum +v_i;
              v_i:=v_i+1;
              end loop;
              dbms_output.put_line(v_sum);
              end;
             
              LOOP 循环 when 退出

              declare
              v_num number(6);
              v_i number(3);
              begin
                 v_sum:=0;
              v_i:=1;
                  loop
              exit when v_i=101;
              v_sum :=v_sum+v_i;
              v_i:=v_i+1;
              end loop;
              dbms_output.put_line(v_sum);
              end;

              LOOP 循环 while 退出

              declare

              v_sum number(6);
              v_i number(3);
              begin
              v_sum := 0;
              v_i:=1;
             
              while v_i <=100
              LOOP
              v_sum := v_sum +v_i;
              v_i:=v_i+1;

              end loop;
              dbms_output.put_line(v_sum);
              end;

              fro循环:
              declare

              v_sum number(6);
              v_i number(3);
              begin
              v_sum := 0;
              for v_i in 1..100
              loop
              v_sum :=v_sum+v_i;
              end loop;
              dbms_output.put_line(v_sum);
              end;
                 
        PL/SQL 与SQL的结合:

                 insert delete update 直接写

                 %type 引用表中字段的类型
                需求: 添加员工  员工号 2000  员工名 撒当

                            declare
                     v_empno  emp.empno%type;
                     v_ename  emp.ename%type;
                     begin
                        v_empno :=2000;
                     v_ename :='冻哈';
                     insert into emp (empno,ename) values(
                         v_empno,v_ename
                     );
                     end;
                    
                根据员工编号 删除该员工记录 
                  declare
         v_empno emp.empno%type;
         begin
         v_empno:=&no;
         delete from emp where empno=v_empno;
         end;

             根据员工号 打印员工姓名

         declare
                v_empno emp.empno%type;
             v_ename emp.ename%type;
             begin
             v_empno := &no;
             select ename into v_ename from emp
             where empno=v_empno;
             dbms_output.put_line(v_ename);
             end;


           根据员工号 打印员工信息
          
           declare
              v_empno emp.empno%type;
              v_empdata   emp%rowtype;
                 begin
             select *  into v_empdata from emp
             where empno=&no;
             dbms_output.put_line(v_empdata.ename||v_empdata.job);
             end;
                  PL/SQL:
               基本数据类型的变量只能存储一条记录
               命名程序:  可重用 安全

                      存储过程
                      触发器
                      函数
                      程序包
                create or replace procedure pro01
                is
                v_char varchar2(20);
                begin
                v_char :='chay';
                dbms_output.put_line(v_char);
                end;

               2.调用存储过程
                     java调用
                     命令调用  exec pro01;
                     过程调用
                       begin
                      pro01;
                      end;

                    ***实用的存储过程
                查询员工号的员工名

                存储过程中的参数
                输入参数;   调用者传递的参数

                输出参数;  返回值

           create or replace procedure pro03(
             v_empno emp.empno%type,
             v_ename  out emp.ename%type
         )
         is
         begin
        
            select ename into v_ename from emp
            where empno=&no;
              
         end;
         注: 调用带有输入参数和输出参数的存储过程
         只能由Java程序和过程调用
         declare
         v_ename emp.ename%type;
         begin
         pro03(7788,v_ename);
         dbms_output.put_line(v_ename);
         end;
        

            独立实现:
                 定义存储过程
                 1根据员工编号 删除员工信息
                       create or replace procedure  pro03(v_empno emp.empno%type)
                 is
                 begin
                   delete from emp where empno=v_empno;
                 end;
                 declare
                 
                  begin
                      pro03(7369);
                   end;


                 2根据特定条件 调整员工薪水
                 根据员工编号
                 工资低于1500 涨1000
                 职位是普通员工 薪水涨300
                 create or replace procedure pro04 (v_empno emp.empno%type)
                 is
                             v_sal emp.sal%type;
                             v_job emp.job%type;
                 begin
                     select sal into v_sal from emp where empno=v_empno ;
                   if(v_sal<1500)  then
                   update emp set sal=sal+1500 where empno=v_empno ;
                   end if;
                   select job into v_job from emp where empno=v_empno;
                   if (v_job='CLEKER')  then
                   update emp set sal=sal+300 where empno=v_empno;    
                   end if;
                   end;

               
                 使用匿名块 打印dept表中的所有数据
                declare
                            v_dept_data dept%rowtype;
                   v_count number(1);
                 begin
                     select count(*) into v_count from dept;
                     for v_i in 1.. v_count
                     loop
                     select * into v_dapt_data
                     from (select * from dept
                     where rownum<=v_i
                     minus
                       select * from dept
                   where rownum <=v_i-1);
                   dbms_output.put_line(v_dept_data.dname||','
                   ||v_dept_data.loc);
                   end loop;
                   end;
                 end;
       使用游标来实现

           declare
              v_data dept%rowtype;

           cursor dept_cursor is select * from dept;
           begin
               open dept_cursor;

            fetch dept_cursor into v_data;

            while dept_cursor%found
            loop
             dbms_output.put_line(v_data.dname||','
                   ||v_data.loc);
                fetch dept_cursor into v_data;
             end loop;
             close dept_cursor;   
           end;
          
           创建一个存储过程 查询某部门的员工数

           create or replace procedure findcount(
              v_deptno emp.deptno%type,
              v_num out number
           )
           is

           begin
           select count(*) into v_num from emp
           where deptno=v_deptno;


           end;
         参数既是输入参数,又是输出参数
         create or replace procedure findcount
         (
         v_num in out number
         )
         is

         begin
               select count(*) into v_num from emp
            where deptno=v_num;
         end;
        
         测试:
         declare
            v_num number(6);

         begin
         v_num :=10;
         findcount(v_num);
         dbms_output.put_line(v_num);
         end;

         异常处理:
         no_data_found
         too_many_rows
         zero_divede
         dup_val_on_index  唯一字段值重复

            输入不存在的用户编号 会抛出异常 no_data_found
         创建存储过程 根据员工号 查询员工的姓名
         create or replace procedure findname(
            v_empno emp.empno%type,
            v_ename out emp.ename%type
         )
         is
         begin
           select ename into v_ename from emp
           where empno=v_empno;

           exception
           when no_data_found then
           v_ename:='不存在';
           when others then
           null;
           end;
    测试:
           declare
           v_ename emp.ename%type;
           begin
           findname(7788,v_ename);
           dbms_output.put_line(v_ename);
           end;
       程序包:

       可以定义存储过程 函数 类型
       定义程序包 并在程序包中定义存储过程

       create or replace package mypack
       is
           procedure hello(v_str varchar2);

       end;
       创建包体 对程序包中存储过程或函数 给出具体的实现
       craete or replece package body mypack
       is
       procedure hello(v_str varchar2)
       is
       begin
         dbms_output.put_line(v_str);
         end hello;
         end mypack;

         测试:
         exec mypack.hello('你好');
         函数:
           必须有返回值

           创建函数计算员工的年薪
           create or replace fundtion emp_income
           (
            v_empno emp.empno%type
           )
           return number
           is
           v_income number(8,2);
           begin
              select (sal+nvl(comm,0))*12 into v_income
           from emp
           where empno=v_empno;
           return v_income;
           exception
           when no_data_found then
           null;
           end;

           测试:
           select emp_income(7788) from dual;

           oracle中提供一种特殊的类型 记录类型
           record 需要用户通过record 自定义类型
           该存储过程需要一个自定义类型的参数 所以必须
           先创建一个程序包 程序包中定义一个记录类型

           create or replace package typepack
           is
             type mytype is record(
               v_ename emp.ename%type,
               v_ sal emp.sal%type,
               v_job emp,job%type
               );
               end;
             创建存储过程 查询员工的姓名 薪水 职位
         使用包中的 自定义类型

         create or replace procedure findemp
         (
            v_empno emp.empno%type,
            v_data out typepack.mytype
         )
         is
         begin
         select ename,sal ,job from emp
         where empno =v_empno;
         end;
         测试:
         declare
           v_data typepack.mytype;
           begin
           findemp(7788,v_data);
           dbms_output.put_line(
           v_data.v_ename||','||v_data.v_sal||','||v_data.v_job);
           end;
           游标:
           游标是一块内存区域 用于存放多条记录
           提供处理多条记录的方案
           创建游标的方式有两种
           方式一
                游标对象
            方式二
           游标变量

         ****** 游标对象
         %found 获取到数据返回true
         %notfount 没有获取数据返回false

         declare
         v_empdata emp%rowtype;
         cursor emp_cursor is select * from emp
            where deptno =10;
            begin
            open emp_cursor;

            fetch emp_cursor into v_empdata;

            while emp_cursor% found
            loop
            dbms_output.put_line(v_empadta.ename);
            fetch emp_cursor into v_empdata
            end loop;
            close emp_cursor;
            end;

            游标对象 使用游标的步骤:
            1. 创建一个游标的对象
            cursor cur is select ...
            2. 打开游标
            open cur...
            3.抓取数据
            fetch cur into v_data...
            4.提取数据
            while cur%found ...
            loop
            ......
            end loop;
            5.关闭游标
            close cur;

                方式二:游标变量 (参照游标变量)

             游标变量:一定明确 PL/SQL中 游标并非类型
             可以定义一个;类型参照游标
             定义一个变量 指定该变量类型为参照游标类型

             declare
              type cur_type is ref cursor;
              v_data cur_type;
              v_empdata emp%rowtype;
              begin
              open v_data for select * from emp
              where deptno=10;
              fetch v_data into v_empdata;
              while v_data%found
              loop
              dbms_output.put_line(v_empdata.ename);
              fetch v_data into v_empdata;
              end loop;
              close v_data;
              end;

              需求:创建存储过程 查询某部门的员工信息
                存储过程需要一个参照游标类型
                必须先创建一个程序包 在其中定义一个
                参照游标类型的变量

                craete or replace package curpack
                is
                     type  curtype is ref cursor;
                end;
             使用自定义的参照游标类型创建存储过程
         create or replace procedure findByDeptno(
               v_deptno emp.deptno%type,
               v_data out curpack.curtype
         )
         is
         begin
         open v_data for select * from emp
         where deptno=v_deptno;
         end;
         测试:
         declare
         v_empdata emp%rowtype;
         v_data curpack.curtype;
         begin
           findByDeptno(10,v_data);
           fetch v_data into v_empdata;
           dbms_output.put_line(v_empdata.ename);
           end;
            独立实现:
         创建存储过程 查询某表的所有数据
           create or replace package curpack
           is
             type curtype is ref cursor;
           end;

           create or replace procedure findBytablename
           (
              v_tablename varchar2,
           v_data out curpack.curtype
           )
           is
           v_sql varchar2(100);
           begin
           v_sql :='select * from ' || v_tablename;
           open v_data for v_sql;
           end;
           测试:
           declare
            v_data curpack.curtype;
         v_tabledata emp%type;
         begin
         findBytablename
         (
            'emp',v_data
         );
         fetch v_data into v_tabledata;
         dbms_output.put_line(v_tabledata.ename);
         end;
         创建一个存储过程,实现分页的功能

         思路:
           确定过程需要输入的参数
           表名 数据当前页数  每页显示数据的条目
           确定过程需要的输出参数
           分页的数据  最大的页数
               create or replace procedure findbypage
         (v_tablename varchar2,
         v_page number,
         v_pageSize number,
         v_data out curpack.curtype,
         v_maxpage out number
         )
         is
         v_datasql varchar2(100);
         v_countsql varchar2(50);
         v_start number(6);
         v_end number(6);
         v_count number(8);
         begin
              v_start:=(v_page-1)*v_pageSize+1;
              v_end:=v_page*v_pageSize;
              v_datasql:=
              'select * from('
              ||'select rownum rn,e.* from '
              ||'(select * from '||v_tablename||') e '
              ||'where rownum<='||v_end||') '
              ||'where rn>='||v_start;
              open v_data for v_datasql;
              v_countsql:='select count(*) from '||v_tablename;         
              --执行SQL语句execute immediate
              execute immediate v_countsql into v_count;         
              if mod(v_count,v_pageSize)=0 then
                   v_maxpage:=v_count/v_pageSize;
              else
                   v_maxpage:=trunc(v_count/v_pageSize)+1;
              end if;         
         end;
              测试:
              declare
                v_data curpack.curtype;
                v_maxpage number(5);
                begin
                findBypage('emp',2,3,v_data,v_maxPage);
                dbms_output.put_line(v_maxpage);
                end;
             事务:
         事务是一组DML语句的逻辑单元
         ACID
         A: 原子性 Atomicity
         事务的逻辑单元中所有的操作 要么都成功 要么都失败
         C:一致性 Consistency
         在事务执行前后 保证数据状态的一致性
         I:隔离性 Isolation
              多个事务之间具备隔离性
           D:持久性 durability
           事务提交 数据的状态将变成永久的

           事务的开启和结束:
            开启:
              DML语句执行 开启一个事务
              事务终止:
              执行commit、rollback结束事务
              连接突然中断(隐式提交)
              DDL操作(隐式提交)
              如果出现其他异常 (隐式提交)
           事务命令:
           commit 提交事务
           rollback 回滚事务
           设置回滚点
           saverpoint p1;
           rollback to p1;

           触发器:
           触发器在数据库里以独立的对象存储
           触发器是由一个事件来启动运行
           触发器不能接收参数
           触发器的组成:
               触发事件
            触发时间  before   after
               触发器本身
            触发频率

           create or replace trigger update_emp_trigger
           after
              update on emp
           for each row
           begin
             dbms_output.put_line('hello');
             end;

             编写一个触发器,在my_emp表中删除数据时  自动在my_emp_bak 表中备份数据

         create or replace trigger delete_trigger
           before
              delete on my_emp
              for each row
              begin
                insert into my_emp_bak
                values(:old.empno,:old.ename);
                end;

  • 相关阅读:
    Superwebsocket 模拟微信聊天室
    python杂记-6(time&datetime模块)
    python杂记-5(装饰器)
    python杂记-4(迭代器&生成器)
    python杂记-3(购买商品)
    python杂记-2(python之文件)
    python杂记-1(os模块)
    淘宝链接中的spm参数
    分布式Web服务器架构(转)
    asp.net网站增加虚拟目录,用来访问网站图片。
  • 原文地址:https://www.cnblogs.com/huangjiangyong/p/12307917.html
Copyright © 2011-2022 走看看