zoukankan      html  css  js  c++  java
  • oracle_学习笔记04

    一:PLSQL

    /*
    		PLSQL编程:procedure Language   过程语言  Oracle于SQL的一个扩展
    		
    		declare
    		--声明变量
    		变量名  变量类型:=初始值
    		vsal    emp.sal%type  --因为不知道表中的变量类型,所以使用引用型变量
    		vrow    emp%rowtype  --声明记录型变量
    		begin 
    			业务逻辑
    		end;
    		
    		--输出语句:dbms_output.put_line(); 
    */
    
    --test1
    declare
      i varchar2(10):='zhugeliang';
    begin
      dbms_output.put_line(i);
    end;
    
    
    --test2:查询员工编号为7369的员工工资,并且打印出来
    declare 
        vsal emp.sal%type;
    begin
        --select sal from emp where empno='7369'; 正常查询结果,下面的语句用into  赋值给变量
        select sal into  vsal from emp where empno='7369';
        dbms_output.put_line(vsal);
    
    end;
    
    
    --test3 查询员工7369的信息,并打印出来
    declare 
           vrow emp%rowtype;
    begin
           select * into vrow from emp where empno='7369';
           dbms_output.put_line('姓名:'||vrow.ename ||'--' ||'工资:'||vrow.sal); --不能用,分隔
    
    end;
    --end;结尾
    

    二:条件判断

    /*
    PL条件判断
    if then 
    	业务逻辑;
    elsif then
    	业务逻辑;
    elsif then
    	业务逻辑;
    else
    	业务逻辑;
    end if;
    
    */
    
    
    --根据不同的年龄,输出相关内容
    
    declare
           age number:=20;       
    begin
      if age < 18 then
        dbms_output.put_line('小孩子');
        
      elsif age > 18  and age <=24 then
        dbms_output.put_line('青年人');
        
      elsif age > 24 and age < 40 then
        dbms_output.put_line('中年人');
           
      else
        dbms_output.put_line('老年人'); 
      end if;
      
    end;
    

    三:循环操作

    /*
    语法1:
    	while 条件 loop
    	...
    	end loop;
    	
    语法二:
    	for 变量  in 起始值..结束值 loop
    	...
    	end loop;
    	
    语法三:
    	loop
    		exit when 条件
    			...
    	end loop;
    
    */
    
    --输出1-10 while循环
    declare
      i number:=1;
    begin
      while i  <=10 loop
        dbms_output.put_line(i);
        i := i + 1;
      end loop;
    end;
    --条件loop后面不要;,end loop;不要忘记
    --i := i + 1;  不支持缩写
    
    
    --输出1-10  for循环
    declare
    
    begin
      for i in 1..10 loop
        dbms_output.put_line(i);
        end loop;
    end;
    --for循环中  i 不需要声明
    
    --loop循环
    declare
           i number := 1;
    begin
           loop 
             exit when i>10;
             dbms_output.put_line(i);
             i := i+1;
           end loop;
    end;
    
    --输出棱形
    /*
    输出m
    	x:[-m,m]
    	y:[-m,m]
    	输出所有棱形满足条件: asb(x)+abs(y)<=m
    	m取任意大于零值
    	
      *  
     *** 
    *****
     *** 
      *
    	
    */
    
    --输出棱形
    
    declare
        m number := 2;
    begin
        for x in -m..m loop
            for y in -m..m  loop
                if abs(x)+abs(y) <=m then
                  dbms_output.put('*');
                else
                  dbms_output.put(' ');
                end if;
            end loop;
                dbms_output.new_line();  --输出新行
        end loop;
    
    end;
    
    --输出倒三角
    declare
        m number := 2;
    begin
        for x in -m..m loop
            for y in -m..m  loop
                if abs(x)+abs(y) <=m and x>=0 then  --注意这里的条件1
                  dbms_output.put('*');
                else
                  dbms_output.put(' ');
                end if;
            end loop;
                dbms_output.new_line();  --输出新行
        end loop;
    
    end;
    
    --输出正三角
    declare
        m number := 2;
    begin
        for x in reverse -m..m loop         --注意这的条件2
            for y in -m..m  loop
                if abs(x)+abs(y) <=m and x>=0 then   --注意这里的条件1
                  dbms_output.put('*');
                else
                  dbms_output.put(' ');
                end if;
            end loop;
                dbms_output.new_line();  --输出新行
        end loop;
    
    end;
    
    
    
    

    四:游标

    /*
    	游标:用来查询结果集:
    	
    	语法:cursor 游标名[(参数名 参数类型)] is 查询结果集
    	
    	开发步骤:
    		1:声明游标
    		2:打开游标    open  游标名
    		3:从游标中取数据  fetch   游标名 into  变量
    						游标名%found:找到数据
    						游标名%notfound:没有找到数据
    		4:关闭游标   close 游标名
    */
    --test1:输出员工表中所有的员工姓名和工资
    declare 
      --声明一个游标
      cursor vrows is select * from emp;
      --声明变量
      vrow emp%rowtype;
    begin
      --1;打开游标
      open vrows;
      --业务逻辑 2;从游标中提取数据
      --遍历循环获取数据
      loop
             fetch vrows into vrow;
             exit when vrows%notfound;
             
            dbms_output.put_line('姓名'||vrow.ename || '工资:' || vrow.sal); --注意语法
      
      end loop;
     
      --3:关闭游标
       close vrows;
    end;
    
    --output
    姓名SMITH2工资:800
    姓名ALLEN工资:1600
    姓名WARD工资:1250
    姓名JONES工资:2975
    姓名MARTIN工资:1250
    姓名BLAKE工资:2850
    姓名CLARK工资:2450
    姓名SCOTT工资:3000
    姓名KING工资:5000
    姓名TURNER工资:1500
    姓名ADAMS工资:1100
    姓名JAMES工资:950
    姓名FORD工资:3000
    姓名MILLER工资:1300
    
    
    --test2:指定部门的所有员工信息
    --声明一个变量记录一行数据
    declare 
      --游标
      cursor vrows(dno number ) is  select * from emp where deptno = dno;
      --声明变量
      vrow emp%rowtype;
    begin
      --1;打开游标,指定10号部门
      open vrows(10);
      --业务逻辑 2;从游标中提取数据
      --遍历循环获取数据
      loop
             fetch vrows into vrow;
             exit when vrows%notfound;
             
            dbms_output.put_line('姓名'||vrow.ename || '工资:' || vrow.sal); --注意语法
      
      end loop;
     
      --3:关闭游标
       close vrows;
    end;
    
    --output
    姓名CLARK工资:2450
    姓名KING工资:5000
    姓名MILLER工资:1300
    
    /*系统引用游标
    1:声明游标:游标名 sys_refcursor 
    2:打开游标: open  游标名 for  结果集
    3:从游标中取数据
    4: 关闭游标
    
    
    
    */
    --输出员工表中所有员工姓名和工资
    declare
      --声明系统引用游标
      vrows  sys_refcursor;
      --声明一个变量
      vrow emp%rowtype;
    
    begin
      --1:打开游标
      open vrows  for select * from emp;
      --2:取数据
      loop
           fetch vrows into  vrow;
           exit when vrows%notfound;
           dbms_output.put_line('姓名'||vrow.ename || '工资:' || vrow.sal);
      end loop;
      --3:关闭游标
          close vrows;
      
    end;
    
    
    /*for循环遍历游标
    不需要声明变量
    不需要打开游标
    不需要关闭游标
    */
    
    --使用for循环遍历游标
    declare
      --声明一个游标
      cursor vrows is select * from emp;
    
    begin
         for vrow in vrows loop
            
            dbms_output.put_line('姓名'||vrow.ename || '工资:' || vrow.sal);
          
         
         end loop;
    end;
    
    
    --按照员工工作给所有员工涨工资:总裁涨1000,经理涨800,其它涨400
    --游标:所有员工
    --变量:声明一个记录一个变量
    
    declare
      --声明一个游标
       cursor vrows is select * from emp;
      --声明一个变量
       vrow emp%rowtype;
    
    begin 
       --1:打开游标
        open vrows;
       --2:循环取数据
        loop
        --获取数据
              fetch vrows into vrow;
              --退出条件
              exit when vrows%notfound;
              
              --3:根据不同的职位,涨工资:总裁涨1000,经理涨800,其它涨400
              if vrow.job ='PRESIDENT' then
                 update emp set sal = sal + 1000 where empno = vrow.empno;  --注意这里使用empno来更新
              
              elsif  vrow.job ='MANAGER' then
                 update emp set sal = sal + 800 where empno = vrow.empno;
              
              else
                 update emp set sal = sal + 400 where empno = vrow.empno;
              
              end if;
              
            
            
        end loop;
       
       --4:关闭游标
       close vrows;
       --5:提交事务
       commit;
    
    end;
    
    select *from emp;  --查看是否更新
    
    

    五: 存储过程

    /*存储过程:实际上是封装在服务器上的一段PLSQL代码,已经编译好了的代码。
    客户端调用存储过程,执行效率会非常高.
    
    语法:
    	create  [or replace ]  procedure  存储过程的名称(参数名  in|out 参数类型,参数名  in|out 参数类型,)
    	is | as 
    	--声明部分
    	begin
    		业务逻辑;
    	end;
    */
    
    --声明一个变量:存储涨工资前的工资
    --查询出当前的工资是多少
    --打印张薪前的工资
    --更新工资
    --打印涨薪后的工资
    
    
    create or replace procedure proc_updatesal(vempno in number,vnum in number)
    is
    --声明一个变量
           vsal number;
    begin
           --查询当前的工资
           select sal into vsal from emp e  where e.empno=vempno;
           --输出涨薪前的工资
           dbms_output.put_line('涨薪前'|| vsal);
           --涨工资
           update emp set sal =vsal + vnum where empno=vempno;
           --输出涨薪后的工资
           dbms_output.put_line('涨薪后'|| (vsal + vnum));
           --提交
           commit;
    
    end;
    
    
    --调用方式1:
    call proc_updatesal(7788,1000);
    
    --调用方式2:
    declare
    
    begin
      proc_updatesal(7788,-1000);
    
    end;
    
    -----------------------------------------------------------------------------------------------------
    
    --指定员工的年薪
    create or replace  procedure proc_gettotalsal(vempno in number,vtotalsal out number) 
    is
      
    begin
        select  sal*12 +nvl(COMM,0) into vtotalsal from emp  where empno=vempno;
    end;
    
    
    --调用
    
    declare
        vtotal number;   --声明一个变量保存年薪
    begin
        proc_gettotalsal(7788,vtotal);   --传到存储过程的输出参数上
        dbms_output.put_line('年薪'||vtotal);
    end;
    
    
    

    六:存储函数

    /*存储函数:实际上是封装在服务器上的一段PLSQL代码,已经编译好了的代码。
    语法:
    	create  [or replace ]  function  存储函数的名称(参数名  in|out 参数类型,参数名  in|out 参数类型,)
    	return 参数类型
    	is | as 
    	--声明部分
    	begin
    		业务逻辑;
    	end;
    
    
    默认是in,必须要有return
    存储过程和存储函数本质上没有任何区别
    存储函数存在的意义是给存储过程调用
    存储函数可以在SQL语句中直接调用
    
    */
    
    --查询指定员工的年薪
    --参数:员工的编号
    --返回值:年薪
    
    
    create or replace function func_getsal(vempno number) return number
    is
       --声明变量,保存年薪
       vtotalsal number;
    
    begin
       select  sal*12 +nvl(COMM,0) into vtotalsal from emp  where empno=vempno;
       return vtotalsal;
      
    end;
    
    
    select * from emp;
    
    --调用存储函数
    declare
           vsal number;
    begin
           vsal:=func_getsal(7788);
           dbms_output.put_line(vsal);
    
    end;
    
    --调用存储函数
    --查询员工姓名和他的年薪
    select ename,func_getsal(EMPNO)  from emp;
    
    
    
    

    七:触发器

    /*
    触发器:当用户执行了  insert|update|delete 这些操作之后,可以触发一系列其它的动作|业务逻辑
    作用:在动作执行之前或者之后,触发业务处理逻辑
    语法:
    	create [or replace] trigger 触发器的名字
    	before | after
    	insert | update | delete
    	on 表名
    	[for each row]
    	declare
    	begin
    	end;
    */
    --插入新员工之后,出出一句话:welcome!
    create or replace trigger tri_test1
    after
    insert
    on emp
    declare
    begin
      dbms_output.put_line('Welcome!');
      
    end;
    
    insert into emp(empno,ename)  values(9528,'huaan');
    
    
    /*触发器的分类:
      语句级触发器:不管影响多少行,都只会执行一次
      行级触发器:  影响多少行,就触发多少次  [for each row]  
      	:old 代表旧的记录,更新前的记录
        :new 代表新的记录,更新后的记录
      
      */
      
    --判断员工涨工资后的工资一定大于涨工资前的工资
    --触发器: before
    --200->100
    --旧的工资大于新的工资,爆出异常,不让它执行
    
    
    create or replace trigger tri_updatesal
    before
    update
    on emp
    for each row
    declare
    
    begin
        if :old.sal > :new.sal then
          
        raise_application_error(-20002,'旧的工资大于新的工资');
        
        end if;
    
    end; 
    
    update emp set sal= sal + 10;  --注意commit
    select *from emp;
    
    
  • 相关阅读:
    IDEA导入外部jar包步骤
    将本地新建工程推到git上
    【转】Memcached与Redis有什么区别
    Redis
    JavaScript-Tool-lhgDialog-js:lhgdialog.js
    信息安全-HTTP:HTTP 身份验证
    信息安全-HTTP:HTTP访问控制(CORS)
    JavaScript-Tool-lhgDialog:框架示例
    JavaScript-Tool-lhgDialog:动画示例-源代码
    JavaScript-Tool-lhgDialog:动画示例
  • 原文地址:https://www.cnblogs.com/zhoujun007/p/12094034.html
Copyright © 2011-2022 走看看