zoukankan      html  css  js  c++  java
  • oracle PLSQL基础学习

    --oracle 练习;
    /**************************************************PL/SQL编程基础***************************************************************/
    --firstday
    --》》》数据类型
    -- Create table
    create table T_CSCUSTOMER
    (
      CUST_NO         VARCHAR2(12) primary key not null,
      PERSON_ID       VARCHAR2(12),
      GROUP_NO        VARCHAR2(12),
      CUST_ADDRESS_ID VARCHAR2(20),
      ORGANISEID      VARCHAR2(10),
      CUST_NAME       VARCHAR2(128),
      CUST_TYPE       VARCHAR2(2),
      SERVE_PASSWORD  VARCHAR2(128),
      REGIONCODE      VARCHAR2(4),
      OPERATOR        VARCHAR2(16),
      OPENDATE        DATE,
      REMARK          VARCHAR2(500),
      ADDRESS         VARCHAR2(256),
      CUST_KIND       VARCHAR2(4),
      LINKMAN         VARCHAR2(64),
      LINKPHONE       VARCHAR2(64),
      LINKMOBILE      VARCHAR2(64),
      COMPANY_ID      VARCHAR2(10),
      INSTALL_ADDRESS VARCHAR2(256)
    )
    
    set serveroutput on
    
    --%TYPE类型
    --SQL> 
    declare
     var_ename t_cscustomer.cust_name%type;
     var_phone t_cscustomer.linkphone%type;
     
     begin
     SELECT cust_name,linkphone
     into var_ename,var_phone
     from t_cscustomer
     where cust_no='0061121890';
     dbms_output.put_line(var_ename||'的电话是:'||var_phone);
     end;
     /
    
    
    --SQL> 
    declare
     var_ename varchar2(200);
     var_phone varchar2(200);
     
     begin
     SELECT cust_name,linkphone
     into var_ename,var_phone
     from t_cscustomer
     where cust_no='0061121890';
     dbms_output.put_line(var_ename||'的电话是:'||var_phone);
     end;
     /
    
    --record类型
    --SQL> 
    declare
    type emp_type is record
    (
    var_ename varchar2(20),
    var_phone varchar2(20),
    var_sal varchar2(200)
    );
    empinfo emp_type;
    begin
    select cust_name,linkphone,address into empinfo from t_cscustomer where cust_no='0110542709';
    dbms_output.put_line('雇员'||empinfo.var_ename||'的电话是'||empinfo.var_phone||'、地址是'||empinfo.var_sal);
    end;
    /
    
    --%rowtype类型
    --SQL> 
    declare
    rowVar_emp t_cscustomer%rowtype;
    begin
    SELECT * into rowVar_emp FROM t_cscustomer where cust_no='0110542709';
    /*输出信息*/
    dbms_output.put_line('雇员'||rowVar_emp.cust_name||'的电话是'||rowVar_emp.linkphone||'、地址是'||rowVar_emp.address);
    end;
    /
    
    --变量  、常量
    var_countryname varchar2(50):='中国';
    con_day constant integer:=365;
    
    --secondday
    --》》》流程控制
    --if
    --SQL> 
    declare
    var_name1 varchar2(20);
    var_name2 varchar2(20);
    begin
    var_name1:='East';
    var_name2:='xiaoke';
    if length(var_name1) < length(var_name2) then
    dbms_output.put_line('字符串“'||var_name1||'”的长度比字符串“'||var_name2||'”的长度小');
    end if;
    end;
    /
    --if elseif 
    --SQL> 
    declare
    num_age int :=55;
    begin
    if num_age>=56 then
    dbms_output.put_line('您可以申请退休了');
    elsif num_age<56 then
    dbms_output.put_line('您小于56岁,不可以申请退休!');
    else
    dbms_output.put_line('对不起,年龄不合法!');
    end if;
    end;
    /
    
    --SQL> 
    declare
    num_age int :=55;
    aboutinfo varchar2(50);
    begin
    if num_age>=56 then
    aboutinfo:='您可以申请退休了';
    elsif num_age<56 then
    aboutinfo:='您小于56岁,不可以申请退休!';
    else
    aboutinfo:='对不起,年龄不合法!';
    end if;
    dbms_output.put_line(aboutinfo);
    end;
    /
    
    --case when
    --SQL> 
    declare
    season int:=3;
    aboutinfo varchar2(50);
    begin
    case season
    when 1 then
     aboutinfo := season||'季度包括1、2、3 月份';
    when 2 then
      aboutinfo := season||'季度包括4、5、6 月份';
    when 3 then
      aboutinfo := season||'季度包括7、8、9 月份';
    when 4 then
      aboutinfo := season||'季度包括10、11、12 月份';
    else
     aboutinfo := season||'季度不合法';
    end case;
    dbms_output.put_line(aboutinfo);
    end;
    /
    
    --》》》循环语句
    --loop语句  一直运行到exit when end_condition_exp 为true时退出
    declare
    sum_i int:=0;
    i int:=0;
    begin
     loop
      i:=i+1;
      sum_i :=sum_i + i;
     exit when i = 100;
    end loop;
    dbms_output.put_line('前100个自然数的和是:'||sum_i);
    end;
    /
    --while 语句
    declare
    sum_i int := 0;
    i int :=0;
    begin
     while i<100 loop
      i:=i+1;
      sum_i:=sum_i+i;
     end loop;
     dbms_output.put_line('前100个自然数的和是:'||sum_i);
    end;
    /
    --for 语句
    declare
    sum_i int:=0;
    begin
     for i in reverse 1..100 loop -- reverse 表示i从100递减
      sum_i:= sum_i+i;
     end loop;
    dbms_output.put_line('前100个自然数的和是:'||sum_i);
    end;
    /
    
    --》》》游标
    /*
    游标属性:
    cur_tmp%found 至少影响到一行数据为true;
    cur_tmp%notfound 与%found相反
    cur_tmp%rowcount 返回受SQL语句影响的行数
    cur_tmp%isopen 游标打开时为true
    */
    --显示cursor
    set serveroutput on
    declare
    cursor cur_emp(var_name in varchar2:='lili')
    is select cust_no,cust_name,address
    from t_cscustomer
    where cust_name like var_name||'%';
    type record_emp is record
    (
    var_empno t_cscustomer.cust_no%type,
    var_empname t_cscustomer.cust_name%type,
    var_empaddress t_cscustomer.address%type
    );
    emp_row record_emp;
    begin
     DBMS_OUTPUT.ENABLE(buffer_size => null);    --表示输出buffer不受限制
     open cur_emp('');
     fetch cur_emp into emp_row;
     while cur_emp%found loop
      dbms_output.put_line(emp_row.var_empname||'的编号是'||emp_row.var_empno||',地址是'||emp_row.var_empaddress);
      fetch cur_emp into emp_row;
     end loop;
     close cur_emp;
    end;
    /
    
    --for 中使用cursor 不用进行打开游标、读取游标、关闭游标 oracle内部自动完成
    declare
    type emp_type is record
    (
    var_ename t_cscustomer.cust_name%type,
    var_phone t_cscustomer.linkphone%type,
    var_sal t_cscustomer.address%type
    );
    empinfo emp_type;
    cursor cur_emp 
    is 
    select cust_name var_ename,linkphone var_phone,address var_sal from t_cscustomer where address like '%招南%0402室%';
    begin
     DBMS_OUTPUT.ENABLE(buffer_size => null);    --表示输出buffer不受限制
     --open cur_emp;
     --fetch cur_emp into empinfo;
     --dbms_output.put_line('共有数据'||cur_emp%rowcount||'条');
     for empinfo in cur_emp loop
      dbms_output.put_line('雇员'||empinfo.var_ename||'的电话是'||empinfo.var_phone||'、地址是'||empinfo.var_sal);
     end loop;
    end;
    /
    
    declare
    cursor cur_emp 
    is 
    select cust_name var_ename,linkphone var_phone,address var_sal from t_cscustomer where address like '%招南%0402室%';
    begin
     DBMS_OUTPUT.ENABLE(buffer_size => null);    --表示输出buffer不受限制
     for empinfo in cur_emp loop
      dbms_output.put_line('雇员'||empinfo.var_ename||'的电话是'||empinfo.var_phone||'、地址是'||empinfo.var_sal);
     end loop;
    end;
    /
    
    begin
     DBMS_OUTPUT.ENABLE(buffer_size => null);    --表示输出buffer不受限制
     for empinfo in (select cust_name var_ename,linkphone var_phone,address var_sal from t_cscustomer where address like '%招南%0402室%') loop
      dbms_output.put_line('雇员'||empinfo.var_ename||'的电话是'||empinfo.var_phone||'、地址是'||empinfo.var_sal);
     end loop;
    end;
    /
    
    --》》》异常处理
    /*
    预定义异常
    自定义异常
    */
    --预定义异常
    declare
    var_empno t_cscustomer.cust_no%type;
    var_empname t_cscustomer.cust_name%type;
    begin
    select cust_no,cust_name into var_empno,var_empname from t_cscustomer where cust_no like '00%';
    if sql%found then
     dbms_output.put_line('雇员编号:'||var_empno||'、名称:'||var_empname);
    end if;
    exception
     when too_many_rows then 
      dbms_output.put_line('返回记录超过一行');
     when no_data_found then
      dbms_output.put_line('无数据记录');
    end;
    /
    --自定义异常
    declare
    primary_iterant exception;--定义一个异常变量
    pragma exception_init(primary_iterant,-00001);--关联错误号和异常变量名
    begin
     insert into dept_tmp values('0','综合部','北京');
     dbms_output.put_line('采用默认值插入dept_tmp成功!');
    exception
     when primary_iterant then
      dbms_output.put_line('主键不允许重复!');
    end;
    /
    
    /**************************************************存储过程、函数、触发器、包***************************************************************/
    --》》》存储过程
    --查看错误
    show errors;
    
    --创建或替换pro_insertTmp
    drop table dept_tmp; 
    create table dept_tmp(
      DEPT_NO         VARCHAR2(12) primary key not null,
      DEPT_NAME       VARCHAR2(50),
      LOCATION        VARCHAR2(200)
    );
    create or replace procedure pro_insertTmp is
    begin
     insert into dept_tmp values(1,'市场拓展部','join');
     commit;
     dbms_output.put_line('插入dept_tmp新记录成功');
    end pro_insertTmp;
    /
    --执行pro_insertTmp
    --execurte pro_insertTmp;
    exec pro_insertTmp;
    
    --程序块中调用pro_insertTmp
    set serverout on
    begin
     pro_insertTmp
    end;
    /
    
    --third day2015-02-03
    /**存储过程参数过程包括:in 输入参数、out 输出参数、in out可被修改的输入参数,并作为输出参数**/
    -->>in
    create or replace procedure pro_insertDept(v_deptno in varchar2,v_deptname in varchar2,v_loc in varchar2) is
    begin
     insert into dept_tmp values(v_deptno,v_deptname,v_loc);
     commit;
     dbms_output.put_line('通过in参数插入dept成功!');
    end pro_insertDept;
    /
    
    --不按顺序传入参数,指定参数值
    begin
     pro_insertDept(v_deptname=>'采购部',v_loc=>'成都',v_deptno=>'2');
    end;
    /
    --按顺序传入参数
    begin
     pro_insertDept('3','市场部','深圳');
    end;
    /
    --混合传入参数
    begin
     pro_insertDept('4',v_loc=>'成都',v_deptname=>'工程部');
    end;
    /
    
    -->>out
    create or replace procedure pro_selectDept(v_deptno in varchar2,v_deptname out dept_tmp.dept_name%type,v_loc out dept_tmp.location%type) is
    begin
     select dept_name,location into v_deptname,v_loc from dept_tmp where dept_no=v_deptno;
    exception
     when no_data_found then
      dbms_output.put_line('该编号的部门不存在!');
    end pro_selectDept;
    /
    
    set serveroutput on
    declare
     v_deptname dept_tmp.dept_name%type;
     v_loc dept_tmp.location%type;
    begin
     pro_selectDept('1',v_deptname,v_loc);
     --if v_deptname = '' then
      dbms_output.put_line(v_deptname||'位于:'||v_loc);
     --end if;
    end;
    /
    
    --执行
    variable v_deptname varchar2(50);
    variable v_loc varchar2(50);
    exec pro_selectDept('2',:v_deptname,:v_loc);
    print v_deptname v_loc;
    select :v_deptname,:v_loc from dual;
    
    -->> in out
    create or replace procedure pro_square(num in out number,flag in boolean) is
    i int:=2;
    begin
     if flag then
      num := power(num,i); --计算平方
     else
      num := sqrt(num); --计算平方根
     end if;
    end pro_square;
    /
    
    declare
     n_number number;
     n_tmp number;
     b_flag boolean;
    begin
     b_flag:=false;
     n_tmp:=3;
     n_number:=n_tmp;
     pro_square(n_number,b_flag);
     if b_flag then
      dbms_output.put_line(n_tmp||'的平方是:'||n_number);
     else
      dbms_output.put_line(n_tmp||'的平方根是:'||n_number);
     end if;
    end;
    /
    
    --in 参数默认值
    create or replace procedure pro_insertDeptDefault(v_deptno in varchar2,v_deptname in varchar2 default '综合部',v_loc in varchar2 default '北京') is
    primary_iterant exception;--定义一个异常变量
    pragma exception_init(primary_iterant,-00001);--关联错误号和异常变量名
    begin
     insert into dept_tmp values(v_deptno,v_deptname,v_loc);
     commit;
     dbms_output.put_line('采用默认值插入dept_tmp成功!');
    exception
     when primary_iterant then
      dbms_output.put_line('主键不允许重复!');
    end pro_insertDeptDefault;
    /
    --指定名称传值
    declare
     row_dept dept_tmp%rowtype;
    begin
     pro_insertDeptDefault('5',v_loc => '太原');
     select * into row_dept from dept_tmp where dept_no='5';
     dbms_output.put_line('部门名称:'||row_dept.dept_name||',位于:'||row_dept.location);
    exception
     when no_data_found then
      dbms_output.put_line('未找到相关的数据!');
    end;
    /
    
    drop table t_emp;
    create table t_emp(
     emp_no number primary key not null,
     emp_name varchar2(20),
     age number,
     sal number,
     job varchar2(20),
     dept_no number,
     address varchar2(200),
     hiredate date
    ); 
    insert into t_emp values(1,'王力',22,9000,'会计',3,'深圳市北京路奥巴马号',sysdate);
    --》》》函数
    create or replace function get_avg_pay(num_deptNo number) return number is
    num_avg_pay number;
    begin
     select avg(sal) into num_avg_pay from t_emp where dept_no=num_deptNo;
     return(round(num_avg_pay,2));
    exception
     when no_data_found then
      dbms_output.put_line('该部门编号的员工不存在');
      return(0);
    end get_avg_pay;
    /
    
    --程序块中调用函数
    declare
     avg_pay number;
    begin
     avg_pay:=get_avg_pay(3);
     dbms_output.put_line('编号为3的部门,平均工资是:'||avg_pay);
    end;
    /
    
    --删除函数
    drop function get_avg_pay;
    
    --》》》触发器
    --语法格式
    create or replace  trigger tri_name
    [before|after|instead of] tri_event
    on table_name|view_name|user_name|db_name
     [for each row][when tri_condition]
    begin
     plsql_sentences;
    end tri_name;
    /
    
    create table dept_log(
     operate_tag varchar2(10),
     operate_time date
    );
    --语句级触发器
    create or replace trigger tri_dept
    before insert or update or delete 
    on dept_tmp
    declare
     v_tag varchar2(20);
    begin
     if inserting then
      v_tag:='插入';
     elsif updating then
      v_tag:='修改';
     elsif deleting then
      v_tag:='删除';
     end if;
     insert into dept_log values(v_tag,sysdate);
    end tri_dept;
    /
    insert into dept_tmp values(6,'业务咨询部','长春');
    update dept_tmp set location='沈阳' where dept_no='6';
    delete from dept_tmp where dept_no='6';
    
    --行级触发器
    create table t_goods(
    id int primary key not null,
    good_name varchar2(50)
    );
    
    create sequence seq_goods_id;
    
    --:new.id--列标识符,新值标识符用于标识当前行某个列的新值“:new.column_name”,通常在insert和update语句中使用
    --:old.id--列标识符,原值标识符用于标识当前行某个列的原始值“:new.column_name”,通常在delete和update语句中使用
    create or replace trigger tri_insert_goods
    before insert
    on t_goods
    for each row
    begin
     select seq_goods_id.nextval into :new.id from dual;
    end;
    /
    
    insert into t_goods(good_name) values('苹果');
    insert into t_goods(id,good_name) values(9,'桃子');
    
    --替换触发器
    --替换触发器定义在视图(一种数据库对象)上,而不是定义在表上。
    create view view_emp_dept
     as select emp_no,emp_name,dept_tmp.dept_no,dept_name,job,hiredate from t_emp,dept_tmp where t_emp.dept_no=dept_tmp.dept_no;
    
    create or replace trigger tri_insert_view
    instead of insert
    on view_emp_dept
    for each row
    declare
     row_dept dept_tmp%rowtype;
    begin
     select * into row_dept from dept_tmp where dept_no=:new.dept_no;
     if sql%notfound then
      insert into dept_tmp(dept_no,dept_name) values(:new.dept_no,:new.dept_name);
     end if;
     insert into t_emp(emp_no,emp_name,dept_no,job,hiredate) values (:new.emp_no,:new.emp_name,:new.dept_no,:new.job,:new.hiredate);
    end tri_insert_view;
    /
    
    --rollback不能再触发器中使用
    create or replace trigger tri_insert_view2
    instead of insert
    on view_emp_dept
    for each row
    declare
     row_dept dept_tmp%rowtype;
    begin
     select * into row_dept from dept_tmp where dept_no=:new.dept_no;
     if sql%notfound then
      insert into dept_tmp(dept_no,dept_name) values(:new.dept_no,:new.dept_name);
     end if;
     insert into t_emp(emp_no,emp_name,dept_no,job,hiredate) values (:new.emp_no,:new.emp_name,:new.dept_no,:new.job,:new.hiredate);
     exception
     --when no_data_found then
      --dbms_output.put_line('部门表中未找到相对应的部门编号');
      --rollback;
    end tri_insert_view;
    /
    
    --若部门中没有编号10,会报错
    insert into view_emp_dept(emp_no,emp_name,dept_no,dept_name,job,hiredate) values (8888,'东方',10,'ACCOUNTING','CASHIER',sysdate);
    commit;
    
    select * from view_emp_dept where emp_no=8888;
    
    --用户事件触发器
    create table t_ddl_oper_log(
     db_obj_name varchar2(20),
     db_obj_type varchar2(20),
     oper_action varchar2(20),
     oper_user varchar2(20),
     oper_date date
    );
    
    create or replace trigger tri_ddl_oper
    before create or drop or alter
    on liulei.schema
    begin
     insert into t_ddl_oper_log values(ora_dict_obj_name,ora_dict_obj_type,ora_sysevent,ora_login_user,sysdate);
    end;
    /
    create table t_test(id number);
    create view view_test as select emp_no,emp_name from t_emp;
    drop view view_test;
    select * from t_ddl_oper_log;
    
    --》》》程序包
    --语法  规范
    create or replace package pack_name is 
     [declare_variable];
     [declare_type];
     [declare_cursor];
     [declare_function];
     [declare_procedure];
    end [pack_name];
    
    --创建一个程序包的“规范”,不包声明体的主体部分
    create or replace package pack_emp is
     function fun_avg_sal(num_deptno number) return number;--获取指定部门的平均工资
     procedure pro_regulate_sal(var_job varchar2,num_proportion number);--按照指定比例上调指定职务的工资
    end pack_emp;
    /
    
    --语法 程序包主体
    create or replace package body pack_name is
     [inner_variable]
     [cursor_body]
     [function_title]
     {
      begin
       fun_plsql;
      [exception]
       [dowith_sentences;]
      end [fun_name]
     }
     [procedure_title]
     {
      begin
       pro_plsql;
      [exception]
        [dowith_sentences;]
      end [pro_name]
     }
     ...
    end [pack_name]
    
    create or replace package body pack_emp is
     function fun_avg_sal(num_deptno number) return number is
      num_avg_sal number;
      begin
       select avg(sal) into num_avg_sal from t_emp where dept_no=num_deptno;
       return(num_avg_sal);
      exception
       when no_data_found then
        dbms_output.put_line('该部门编号不存在雇员记录!');
        return 0;
      end fun_avg_sal;
    
     procedure pro_regulate_sal(var_job varchar2,num_proportion number) is
      begin
       update t_emp set sal=sal*(1+num_proportion) where job=var_job;
      end pro_regulate_sal;
    end pack_emp;
    /
    
    --调用包
    set serveroutput on
    declare
     num_deptno t_emp.dept_no%type;
     var_job t_emp.job%type;
     num_avg_sal t_emp.sal%type;
     num_proportion number;
    begin
     num_deptno:=5;
     num_avg_sal:=pack_emp.fun_avg_sal(num_deptno);
     dbms_output.put_line(num_deptno||'号部门的平均工资是:'||num_avg_sal);
    
     var_job := 'SALEMAN';
     num_proportion:=0.1;
     pack_emp.pro_regulate_sal(var_job,num_proportion);
    end;
    /
  • 相关阅读:
    iOS 10 因苹果健康导致闪退 crash-b
    iOS10 配置须知-b
    iOS开发 适配iOS10以及Xcode8-b
    iOS 10 的适配问题-b
    mybatis中分页查询
    mybatis开发流程,增删改查
    spring mvc接收参数方式,json格式返回请求数据
    xml配置文件中常见的命名空间解释
    myeclipse中配置schemaLocation路径,实现xml文件自动提示
    spring MVC工作流程
  • 原文地址:https://www.cnblogs.com/superjt/p/4274329.html
Copyright © 2011-2022 走看看