zoukankan      html  css  js  c++  java
  • oracle 学习之 PL/SQL

    /*
      PL/SQL : Oracle内部语言
      SQLServer的是:TSQL
      Procedural Language/SQL 是oracle在标准的SQL语言上的扩展,PL/SQL不仅允许嵌入SQL语言,还可以
      定义变量和常量,允许使用条件语句和循环语句,允许使用例外处理各种错误,这样使得它的功能变得
      更加的强大.
      
      优点:提高应用程序的运行性能,模块化的设计思想,减少网络传输量,提高安全性
             
      SQL语言:有两种SQL1992/SQL1996  没有循环控制结构
      
      PL/SQL块由三个部分组成:定义部分,执行部分,例外处理部分
      declare
           定义部分 -- 定义常量,变量,游标,例外,复杂数据类型
      begin
           执行部分 -- 要执行的PL/SQL语句和SQL语句
      exception
           例外部分 -- 处理运行的各种错误
      end;
      
      调用过程
      exec 过程名
      call 过程名                
    */
    
    --匿名块
    
    
    --简单打印一句话
    
    --打开显示
    set serveroutput on ;
    
    begin
      dbms_output.put_line('Hello PL/SQL!');
    end ;
    /
    
    
    /*
        变量声明的规则
        1 变量名不能够使用保留字
        2 第一个字符必须是字母
        3 变量名最多包含30个字符
        4 不要与数据库的表或者列同名
        5 每一行只能声明一个变量
        
        常用的变量类型
        1 binary_integer : 整数,主要用来计数而不是用来表示字段类型
        2 number: 数字字符
        3 char : 定长字符串
        4 varchar2 : 变长字符串
        5 data : 日期
        6 long : 长字符串最长2GB
        7 boolean : 布尔类型,可以取值true|false和null值
        
    */
    
    
    --声明变量
    declare v_name varchar2(20) ;
    
    declare
    	v_temp number(1);
    	v_count binary_integer :=0;
    	v_sal number(7,2) :=4000.00;
    	v_date date :=sysdate ;
    	v_pi constant number(3,2) :=3.14;
    	v_valid boolean :=false;
    	v_name varchar2(20) not null :='hello plsql' ;
    begin 
    	dbms_output.put_line('v_temp value :'||v_temp);
    end;
    
    --根据表中字段类型声明变量类型的
    declare 
    	v_empno number(4);
    	v_empno2 emp.empno%type;
    	v_empno3 v_empno2%type;
    begin
    	dbms_output.put_line('test');
    end;
    
    /*
      复杂变量
      Table变量类型 : 集合  (表示集合时要自己定义的一个新的数据类型)
      Record变量类型 : 类 (代表实体,一条记录)
    */
    --定义Table变量类型
    --Table 变量类型(数组)
    declare
    	type type_newname is table of emp.empno%type index by binary_integer; --声明一个数组类型 index by binary_integer 指系统创建一个主键索引,以引用记录表变量中的特定的行。
    		v_empnos type_newname ;  --用数组类型定义变量
    begin
    	v_empnos(0) :=7369;
    	v_empnos(2) :=7839;
    	v_empnos(-1):=9999;
    	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 :=50 ;
    	v_temp.dname  :='aaa';
    	v_temp.loc    :='bj';
    	dbms_output.put_line(v_temp.deptno || ' ' || v_temp.dname);
    end;
    
    --使用%rowtype 声明record变量
    declare
    	v_temp dept%rowtype;   --直接用一张表的行来定义record,表结构变化时record也在变
    begin
    	v_temp.deptno :=50;
    	v_temp.dname  :='aaa';
    	v_temp.loc    :='bj';
    	dbms_output.put_line(v_temp.deptno||' '||v_temp.dname);
    end ;
    
    /*
        PL/SQL中的SQL语句
        select 语句返回有且只有一条记录
    */
    --select语句
    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_temp emp%rowtype;
    begin
    	select * into v_emp from emp where empno=7369;
    	dbms_output.put_line(v_temp.ename);
    end;
    
    
    --insert 语句
    declare
    	v_deptno dept.deptno%type :=10;
    	v_dname dept.dname%type :='aaa';
    	v_loc dept.loc%type :='beijing' ;
    begin
    	insert into dept2 values(v_deptno,v_dname,v_loc);
    	commit;
    end;
    
    --update语句
    declare
    	v_deptno emp2.deptno%type :=10 ;
    	v_count number;
    begin
    	update emp2 set sal = sal/2 where deptno = v_deptno ;
    	--select deptno into v_deptno from emp2 where empno = 7369;
    	--select count(*) into v_count from emp2 ;
    	dbms_output.put_line(sql%rowcount||'条记被影响');
    	commit ;
    end;
    
    --DDL语句
    begin
      execute immediate 'create table t_temp(nnn varchar2(20) default "aaa")' ;
    end ;
    
    --语句块
    declare
    	v_name varchar2(20);
    begin
    	v_name := 'jack' ;
    	dbms_output.put_line(v_name);
    end;
    
    --带异常捕获的语句块
    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;
    
    --分支语句
    --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;
    
    --循环  (相当于do...while)
    declare
    	i binary_integer :=1;
    begin
    	loop 
    		dbms_output.put_line(i);
    			i := i+1 ;
    			exit when(i>=11);
    	end loop;
    end;
    
    declare
    	j binary_integer :=1;
    begin
    	while j<11 loop
    		dbms_output.put_line(j);
    			j := j+1 ;
    	end loop ;
    end;
    
    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=2222;
    exception
    	when no_data_found then
    		dbms_output.put_line('没数据');
    end;
    
    --错误记录
    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;
    
    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 * from errorlog;
    

    触发器

    /*
      触发器 trigger
    	触发器必须依附于表才能起作用
    */
    
    --创建日志表 emp_log,用于记录对表emp的所有操作日志
    create table emp_log
    (
    	uname varchar2(20),
    	action varchar2(10),
    	atime date
    );
    
    --创建触发器
    /*
    	触发条件:insert|delete|update 对某张表做插入|删除|更新的操作
    	触发时间:after|before 操作之后|操作之前
    	触发行:each row 操作影响一行触发一次,不写表求一次操作触发一次
    */
    create or replace trigger trig
    	after insert or delete or update on emp for each row
    begin
    	if inserting then
    		insert into emp_log(uname,action,atime) values(USER,'insert',sysdate);
    	elsif updating then
    		insert into emp_log(uname,action,atime) values(USER,'update',sysdate);
    	elsif deleting then
    		insert into emp_log(uname,action,atime) values(USER,'delete',sysdate);
    	end if ;
    end;
    /
    
    --触发
    update emp set sal=sal*2 where deptno=30;
    delete from emp where empno = 7369 ;
    
    
    --查看日志表
    select * from emp_log;
    
    --? : 有外键关系时,主表中的主键存在外表的引用关系,因此不能随意更新,但可以用触发器解决这个问题
        --如: update dept set deptno=99 where deptno=10
    
    --删除触发器
    drop trigger trig;
    
    create or replace trigger trig
    	after update on dept for each row
    begin
    	update emp set deptno = :NEW.deptno where deptno = :OLD.deptno ;
    end;
    /
    /*
    	通常一条update语句会产生新旧两个状态 :NEW代表新状态 :OLD代表旧状态
    */
    update dept set deptno=99 where deptno=10;
    



  • 相关阅读:
    索引!
    事件event
    Erlang运行时源码分析之——线程进度机制
    Erlang 运行时中使用的读写锁解析
    经典互斥算法解析
    网格布局之grid
    注册简单表单
    前端入门之自我介绍
    Python之一后置固件yield和终结函数addfinalizer
    python中yield 与 return 区别
  • 原文地址:https://www.cnblogs.com/java20130726/p/3218313.html
Copyright © 2011-2022 走看看