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;
    /

  • 相关阅读:
    Android studio中Rendering Problems不能可视化操作的解决办法
    java实现最基础的socket网络通信
    java入门
    Android开发环境的搭建
    python学习笔记之初识Python
    用例图
    经典算法学习之回溯法
    结构化分析和方法
    经典算法学习之分治法(以排列、组合程序为例)
    day22_1-课前上节复习+os模块
  • 原文地址:https://www.cnblogs.com/zemax/p/5340665.html
Copyright © 2011-2022 走看看