Oracle基本操作

/*
     @author:luowen
     @time:2013-12-04
     @desc:oracle base operations 

Oracle notes

1 创建用户
    create user username identified by password; //创建用户名和密码
    grant create session to username; //给创建的用户授权

2 给用户赋权限
    grant privilege/role to username;
    eg:
        grant connect to username; //是username拥有登入权限
        grant resource to username; //给username普通的权限

3 回收用户权限
    revoke privilege/role from username;
    eg:
        revoke connect from username; //回收username登入权限
        revoke resource from username; //回收普通股的权限

4 删除用户
    drop username [cascade]; //删除用户[cascade]级联的东西都删除掉

5 创建表
    create table user (id number); //创建一个user表,字段只有一个id;

6 用户a查询用户b创建的表(默认是a用户查询不到用户b创建的表的) --> (Oracle 方案概念)
    b用户:
        grant select[update,insert,delete]/[all] on tableName to a //用户a可以查询用户b创建的表.

        如果来了个c用户,要从a用户拿到b用户的访问b表的权限时候,b用户授权的时候需要加上"with grant option"-> grant [select,update,delete,insert[all]] on tableName to a;
       "with grant option" -> 对象权限
       "with admin option" -> 系统权限

7 Oracle 启动流程

    1.windows
        a.cd Orcale/bin/lnsrtlt.exe start; //启动监听
        b. //启动数据库实例

8 Oracle用户管理    
     1.用户登入限制
        create profile profileName limit failed_login_attempts 3 password_lock_time 2; //当用户输入密码错误超过3次的是,用户将被搜定2天
        alter user userName profile profileName; //将配置的文件分配给指定用户userName;
        alter user userName account unlock; //给锁定用户解锁
    2.oracle终止口令
        create profile profileName limit password_life_time 10 password_grace_time 2; //限制用户的密码生存时间为10天,宽限是时间为2天,到期自动要求用户更改密码;
        alter user userName profile profileName; //将配置的文件分配给用户

9  Oracle用户验证
    1.wondows
        当登入windows的用户在orl_dba用户组中时候,该用户可以跳过验证
            conn xxx/xxx as sysdba //可以跳过验证,直接登入到oracle //解决方案 -> (1) 可以到orl_dba用户组中将该用户删除;(2) 可以直接到oracle安装目录中搜索 sqlnet.ora,将用户验证方式NTS修改为NONE,可以,不适用oracle的系统验证方式。
        当登入windows的用户不在orl_dba用户组中时候,则选择数据验证方式。
   2. sys在oracle拥有最高权限,system适用系统验证登入时候,也会自动切换到sys用户。

10 当管理密码丢失时候(解决方案)
    1.在Oracle安装目录中搜索pwd[数据对象实例].ora(二进制形式)
    2.拷贝该文件,以备后用,删除该文件.
    3.在dos命令行创建一个新的文件
        orapwd file=原来密码文件的全路径密码文件.ora password=新密码 


11 Oracle 建表
    create table table_name (
        列1 Oracle数据类型,
        列2 Oracle数据类型,
        列3 Oracle数据类型,
        列4 Oracle数据类型,
    );

    Oracle 数据类型
        char(size) -> 2k个字符(定长);
        varchar2(size) -> 4k个字符(不定长)
        nchar(size) -> 2k个字符(Unicode编码)(定长)[一个汉字占用一个字符]
        nvarchar(size) ->4k个字符(Unicode编码)(不定长)[一个汉字占用一个字符]
        clob(character large object) -> 字符型大对象,最大8tb(不定长)[只能存字符类型]
        blob(binary large object) -> 二禁止类型大对象,最大8tb(比定长)[可以存二进制](很少用,占用网络带快,速度慢,实际记录文件存放路径)
        number -> 可以放整数,可以放小数,number(p,s) p为整数,s为小数 1 <= p <= 38,-84 <= s <= 127(不定长)
        number(n,m) -> 有效位为n,小数点为m位!
        date(日期类型) -> 用于表示时间(年/月/日/时/分/秒)Oracle默认格式为(dd-mm-yy)希望添加自己的喜欢的格式添加时,我们需要添加Oracle的函数
        timestamp(n) -> 时间戳,当表中的字段更改的时候,timestamp会跟着联动(不推荐);

12 建表实例
    1.students 表
        create table students(
            id number,
            name varchar2(64),
            sex char(2),
            birthday date,
            fellowship number(10,2),
            resume clob
        );
        2 class 表
            create table class_(
                id number,
                name varchar2()
            )
        3.修改表的操作
            alter table table_name drop column;
            alter table table_name add .......etc.

13 Oracle 的crud操作
    1.SELECT
        select *[column] from table_name where [conditions] order by [column];
    2.INSERT
        insert into table_name (column) values (column);
    3.DELETE
        delete from table_name where [conditions];
    4.UPDATE
        update table_name set [column] = [values] where [condition];

    
    注意:Oracle中 null = ' '、Oracle中字符串需要用 ''包裹起来,查询时,如需要去重复,可以添加关键字 eg: select distinct * from tab_name;

13 Oracle的一些函数
    1.abs() //求平均值
    2.count() //求总数
    3.substr() //截取
    4.replace() //替换
    5.nvl() //判断为空
    6.concat() //连接字符
    7.ltrim() //剪切左边部分
    8.rtrim() //剪切右边部分
    9.max(); //求最大值
    10.min() //求最小值
    etc.....

plugin tips -> 我们希望删除用户,同事保存该用户的数据对象
    方案: 我们可以将该用户锁定 alter user username account lock;
                          解锁 alter user username account unlock;

14 Oracle的分页操作
    MySQL:select * from table_name limit start ,count;
    SqlServer: select top 10 * from table_name where id not in(select top 4 id from table_name where conditon ); //排除前四条,去除了第5条到14条
    Oracle: select t2.* from (select t1.*,rownum rn from (select * from emp) t1 where rownum <= 3) t2 where t2.rn >= 1;
        第一层:select * from table_name where condition;
        第二层:select t1.*,rownum from (select * from table_name where condition) t1 where rownum <= 3;
        第三层:select t2.*,rownum from (select t1.*,rownum from (select * from table_name where condition) t1 where t1.rownum <=3 ) t2 where t2.rownum >=9; //这个查询中,记住第二个条件需要判断的是最小值,然后第三层是限定最大值 (先小后大)


    复制表
        create table table1 like table2; -----------|
                                                    |---->将table2 replication to table1;
        create tabl table1 select * from table2 ----|

   复制表内容
        insert into table1 select * from table2;
        select * into table1 from table2;


15 Oracle
    union 简单的去两个查询语句的并集
    union all 简答的和两个查询结果进行并集,并不排序,不去重复

    minus 查询两个查询语句的差集(去掉两个集合中公共有的部分,如果没有,就去第一个集合的结果)
    cube select avg(sal),deptno,job from emp group by cube(deptno,job); //查询每个部门,部门的每个职员的平均工资

    内连接
        select emp.job,dept.dname from emp,dept where emp.deptno = dept.deptno;
        select emp.job,dept.dname from emp inner join dept on emp.deptno = dept.deptno;
        特点:只有两张表,两个结果集里面同时满足的时候,才会被选中。
    外连接
        左外联:select emp.job,dept.dname from emp left join dept on emp.deptno = dept.deptno; //emp表的内容与dept表中没有匹配,也要全部被显示
        右外联:select emp.job,dept.dname from emp right join dept on emp.deptno = dept.deptno; //emp表的内容与dept表中没有匹配,也要全部被显示
        select emp.job,dept.dname from emp ,dept where emp.deptno = dept.deptno(+); //同上也是有外链,只是写法的不同 
    完全外联
        select emp.job,dept.dname from emp full outer join dept on emp.deptno = dept.deptno; //当不匹配的,也全部显示出来

16.java链接Oracle
    1.jdbc
            package com.luowen.jdbc;

            import java.sql.Connection;
            import java.sql.DriverManager;
            import java.sql.ResultSet;
            import java.sql.SQLException;

            import com.mysql.jdbc.Statement;


            public final class JdbcUtils {
                private static String driver = "com.mysql.jdbc.Driver";
                private static String url = "jdbc:mysql://localhost:3306/";
                private static String database = "test";
                private static String user = "root";
                private static String password = "luowen";
                
                
                private JdbcUtils(){
                    
                }
                
                static{
                    try {
                        //加载驱动
                        Class.forName(driver);
                    } catch (Exception e) {
                        throw new ExceptionInInitializerError();
                    }
                }

                public static Connection getConnection() throws SQLException{
                    return DriverManager.getConnection(url+database,user,password);
                    
                }
                
                public static void close(ResultSet rs,Statement sm,Connection conn){
                    
                    try {
                        if(rs != null)
                            rs.close();
                    } catch (Exception e) {
                        // TODO: handle exception
                        e.printStackTrace();
                    }finally{
                        try {
                            if( sm != null)
                                sm.close();
                        } catch (Exception e2) {
                            // TODO: handle exception
                            e2.printStackTrace();
                        }finally{
                            try {
                                if(conn != null)
                                    conn.close();
                            } catch (Exception e3) {
                                // TODO: handle exception
                                e3.printStackTrace();
                            }
                        }
                    }
                }

            }

    2 桥链接(odbc)
        在window里面设置数据源(odbc) java代码里只要更改driver 和 url 就可以了

17 适用子查询实现Oracle的行迁移
    create table temp# as select * from table_name where id < 10000; //将table_name中的id小于10000的数据迁移到temp#表中
    update emp set (job,sal,comm) = (select job,sal,comm from emp where ename= "SMISTH"); //支持将表的多个字段更新

18 Oracle 函数
    1.to_date();
        to_date("1909-11-12",'yyyy-mm-dd'); //把字符串转化成制定格式的日期
      to_char();
        to_char(); //将日期格式转化成字符串格式

    2.replace(field,'old','new'); //将查询的结果,替换显示,但数据库中的数据没有更改!

    3.instr(c1,c2,I,J) //c1->被搜索的字符,c2->希望搜索的字符,I->从第几个开始查,J->从哪里结束。 返回出现的位置

    4.ascii('a') -> 97 //返回给定字符的asciii值

    5.chr(97) -> 'a' //给定一个数字,返回一个字符

    6.concat(); //链接两个字符函数
        select concat(ename,'是好人') from emp;    //将两个字符连接起来
        select ename || '是好人' from emp;        //同上

    7.initcap('adfsdf') -> Adfsdf; lcase('asdfsf') --> 转大写; ucase("SDFSDF") -> 转小写; //返回字符串大写

    8. trim(" ","asdfsdf   ") // 清除函数

    9.ceil(); //向上取整 ->(天花板)

    10.floor(); //向下取整 ->(地板)

    11.mod(); //取模函数 select mod(3,2) from dual; 3除以2返回1

    12.round() //用户四舍五入 round(3.444) -> 3;

    13.trunc() //直接去掉小数点后面数 trunc(1.333); -> 1;

    14.add_mouths(); //去除三个月入职的员工 select * from emp where add_mouths(hiredate,3) >= sysdate;

    15.last_day(); //返回这个月的最后一天

19 Oracle事务处理机制 --> transaction
    | savepoint aa; //保存点aa
    | savepoint bb; //保存点bb
    | rollback bb; //回馈到aa
    | rollback aa; //回馈到bb
   / //回馈到aa,就不能回馈到bb了
   一旦commit后,所有的东西都rollback 不了了

20 Oracle  数据完整性

    1. not null //非空
    2. unique //限制数据为唯一,Oracle可以存入多个空
    3. primary key //不能重复,不能为空
    4. foreign key(外键);//两张表通过外键联系 create table stu(id number primary key,name varchar2(36) not null,classid number references class(id)); create table class (id number unique,name varchar2(32)); //学生表和班级表通过classid来联系,foreign key 必须是主键,或是唯一,且数据类型是一致的.
    5.cheack(); //create table user (id number primary key,sal number cheace(sal >=1000 and sal <=50000)); //添加的数据sal必须在cheack范围内


21 Oracle 的权限和角色
    系统权限
      授权:
        select * from system_privilege_map order by name;
        grant create session;
        grant create table;
        grant create view;
        grant create trigger
        grant create procedure
        etc...
        选项:with admin option; 
      回收:
        revoke create session from user_name  //系统权限不能联机回收

    对象权限
        授权:
            grant select,update on Obj.table to user_name;
            etc ...
            选项: with grant option
        回收:
            revoke select , update on table.colum from user_name; //回收具有联机效应

    角色(connect,dba,resource)
        select * from dba_roles; //查看系统的角色信息
        select * from dba_sys_privs where grantee = "DBA"; //查看DBA角色的权限
        select * from dba_role_privs where grantee="user_name"; //查看用户是什么角色
        
    自定义角色:
        create role role_name not indentified; //创建一个role_name的角色
        grant create session to role_name;
        grant select on scott.emp to role_name;
        grant delete on scott.emp to role_name;
        grant update on scott.emp to role_name;
        etc ..    //给role_name 赋权限
    给角色给用户户
        grant 角色名 to user;
        grant role_name to user_name;  //给用户user_name赋上了role_name 的角色!

    删除角色:
        drop role role_name;

添加约束
    alter table table_name add constraint constraint_name [unique,primary key,cheack(),foreign key] (field);
    alter table table_name modify field [not null]
删除约束
    alter table table_name drop constraint constriant_name; //指定约束名
    alter table table_name drop primary key; //一张表中只有一个主键
序列(sequence)[可以为表中自动添加值,可以为多个用户共享]
    create sequence my_sequence //my_sequence 序列名
        start with 1            //从1开始
            increment by 1      //增长1
            minvalue 1          //最小值1
            maxvalue 30000      //最大值3w
            cycle               //当数据达到3w时候,循环
            nocache             //不保留缓存
    使用
        insert into table_name values(my_sequence.nextval,'insert_name');
        select my_sequence.currval from dual; //产看当前sequence到哪里了
    删除序列(delete sequence)
        drop sequence sequence_name; //删除序列名为sequence_name的序列
    索引
        create index index_name on table_name(column);

    创建过程并可以实现输入参数
        create procedure pro_demo (in_id in number,in_name in varchar2)
        is
        begin
        update emp set ename = in_name where empno = in_id;
        end;
        /                   //->结束
        exec pro_demo(12,'smith');      //调用过程
        call pro_demo(12,'smith');      //调用过程

    创建Oracle 函数
        created function func1(in_name varchar2)
        return number is
        declare
        out_sal number;
        begin
        select (sal+nvl(comm,0))*13 into out_sal from emp where ename = in_name;
        return out_sal;
        end;
        /                    --//结束

    创建Oracle包  (包是问了更好的管理自的写的函数,过程.类似java超类)

        create [ or replace ] package package_name is
        --声明过程
        procedure 过程名(变量 变量类型);
        --0声明函数
        function 函数名(参数 变量) return 反悔变量名;
        end;

    包体(实列化包)
        create or replace package body 包名 is
        ---实现过程
        create or replace procedure pro_name(参数 参数类型)    --//对应包中的过程名
        is
        begin
        insert into emp (...) values (.....);         //对应执行语句
        end;
        ---实现函数
        create function funtion_name(参数 参数类型)
        return 返回参数类型
        is
        begin
        select ..............;               --//对应执行语句
        end;
        end;
22 PL/SQL编程
    PL/SQL语法定义
    1.标量类型(scalar);  
    2.复合类型(composite);
    3.参照类型(reference);
    4.lob(large object);
    
    pl/sql 是一种基于sql的扩张编程语言,可以定义变量,可以实现条件判断,循环等。
    pl/sql 可以开发,存储过程,函数,包(包体),触发器 //一块为单位的

    create procedure pro1 is 
    begin
        insert into emp values("11",'sdfdf');
    end;
    /                          //一个最简单的存储过程.

    带参数的存储过程
     create procedure pro1(id number) is begin delete from emp where empno = id; end; /                    //删除出入的id对应的数据

     块实例
     declare
     /------------注释部分---------------/
     begin
     /------------注释部分---------------/
     exception
     /------------注释部分---------------/
     end;

    eg. 打印hello word

    begin
        dbms_output.put_line('hello word');
    end;
    /
    //开启自动打印功能
    set serveroutput on;

    eg2.
        declare
        --------定义一个变量
        v_ename varchar2(32);

        begin
        ---------//开始执行
        select ename into v_ename from emp where ename = &ename;  --------//从表中查询出来ename给v_ename  &ename会弹出一个对话框,输入值
        dbms_output.put_line('雇员名是:' || v_ename);

        end;
        ----------//定义结束
        / -----------//结束标记符号

    
Oracle复合数据
    格式:
        create or replace procedure pro_demo1(v_in_empno in number)
        is
        ----//定义了一个变量,该变量就是记录类型(复合类型)注:类似定义了一个对象,对象里面存放了成员变量
        type luowen_emp_record is record(
            v_ename emp.enam%type,
            v_sal emp.sal%type,
            v_job emp.job%type
        );
        v_emp_record luowen_emp_record;            ---//变量 v_emp_record 的类型是luowen_emp_record
        begin
            select ename,sal,job into v_emp_record from emp where empno = v_in_empno;
            dbms_output.put_line('名字:'||v_emp_record.v_ename || '工资:'||v_emp_record.v_sal );
        end;

     类似数组类型
        declare
            type sp_table_type is table of emp.ename%type    ---//声明sp_table_type 是 table 类型
            index by binary_integer;
            sp_table sp_table_type;        --/定义变量sp_table 的类型为sp_table_type
        begin
            select into sp_table(-1) from emp where empno = 7788;  -----//将查出来的值复给sp_table(-1)中
            dbms_output.put_line('xxxx');
        end;
        /

    参照变量(reference)
        游标变量cursor
            1.定义游标
                type 自定义游标名字 is ref cursor;
                变量名 自定义有标名;

            2.打开游标
                open 游标变量 for select 语句 ------;

            3.取出当前游标
                fetch 游标变量 into 其他变量;

            4.判断游标是否是最后的记录
                游标变量%nofound
            
            eg:
                create or replace procedure pro_demo2(v_in_deptno number) is
                    type luowen_emp_cursor is ref cursor;           ----//定义一个游标变量
                    v_emp_cursor luowen_emp_cursor;         -----//定义标量 v_emp_cursor 类型是luowen_emp_cursor;
                    v_ename emp.ename%type;   ---//定义变量保存查出的数据
                    v_sal emp.sal%type;  ------//定义一个变量保存出查出的薪水
                begin
                    open v_emp_cursor for select ename,sal from emp;  ---------//将游标适用到select 语句中
                loop
                    fetch v_emp_cursor into v_ename,v_sal;       ---//适用循环
                    exit when v_emp_cursor%notfound;      ---//判断是否达到了末尾,达到则对出
                    --dbms_output.put_line('用户名:' || v_ename || '薪水:' || v_sal);       --//打印查出的数据
                    if v_sal < 200 then
                        update emp set sal = sal + 100 where ename = v_ename;          ------//查询出结果为小于200的员工自动加上100元的薪水
                    end if;
                end loop;     ---//结束循环
                    close v_emp_cursor;       ---//关闭游标
                end;


Oracle 分支语句 (emp表中如果job是president的人工资加上1000 为manager的加上500 其他的加上100)
        create or replace procedure pro_demo2(v_in_empno in number) is
        v_job emp.job%type;
        begin
        select job into v_job from emp where enpno = v_in_empno;
        if v_job = 'PRESIDENT' then
            update emp set sal = sal + 1000 where empno = v_in_empno
        elseif v_job = 'MANAGER' then
            update emp set sal = sal+ + 500 where empno = v_in_empno;
        else
                update emp set sal = sal + 100 where empno = v_in_empno;
        end if;
        end;
        /

Oracle循环(给一张表中添加100条数据)
    create table user(id number,username varchar2(32));

    create or replace procedure insert_pro(in_username in varchar2,in_num in number)
    is
    v_start number := 0;
    begin
    loop
        insert into user values(v_start,in_username);
        exit when v_start = in_num;
        v_start := v_start + 1;
    end loop;
    end;

oracle while循环
    create or replace pro_demo3(v_in_name varchar2,v_in_num number) is
    v_empno number := 200;
    begin
        while v_empno <= 200 + v_in_num loop
             insert into users values(v_empno,v_in_ename);
        end loop;
        end;


oracle 带有返回结果的procedure
    返回普通的字串
        create or replace procedure pro_demo(in_empno in number,out_ename out varchar2)
        is
        begin
            select ename into out_ename from emp where empno = in_empno;
        end;
            ----//返回结果
       -------//在Java中调用
        Class.forName("oracle.jdbc.driver.OracleDriver");     //加载驱动
        Connection ct = DiverManage.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl","scott","tiger"); //得到链接
        String sql = "{call pro_demo(?,?)}"; //定义sql语句
        CallableStatement cs = ct.prepareCall(sql); //构建预定statement
        cs.setInt(1,7839); //定义?的值
        cs.registerParameter(2,oracle.jdbc.OracleType.VARCHAR); //注册过程pro_demo返回值得容器
        cs.execute(); //执行过程
        String res = cs.getString(2); //取回过程返回的值.

oracle 分页过程 (in_table_name[需要查询的表],in_pagesize[当前页显示多少条数据],in_pagenow[显示当前为第几页],out_cursor[定义返回的游标,用于返回的数据],out_cnt[数据的总数],out_pagecnt[数据的分页数])
    create or replace procedure pagePro(in_table_name varchar2,in_pagesize in number,in_pagenow in number,out_cursor pack1.demo_cursor,out_cnt out number,out_pagecnt number)
        is
    v_start number;
    v_end number;
    v_sql varchar2(2000);
    begin
    v_start := in_pagesize * (in_pagenow - 1); ---//定义当前页显示多少条数据
    v_end := in_pagesize * pagenow; ----//定义当前页
    v_sql := 'select t2.* from (select t1.*,rownum cnt from (select * from '|| in_table_name ||') t1 where rownum <= '|| v_end ||') where t1.cnt >=' || v_start;  ---//分页查询语句
    select count(*) into out_cnt from emp; //查询共有多少条数据
    if mod(out_cnt,in_pagesize) = 0 then   //判断是否能整出
    out_pagecnt := out_cnt/in_pagesize;    //整出的页数
    else
    out_pagecnt := out_cnt/in_pagesize + 1; //不能整出的页数
    end if;
    open out_cursor for v_sql;      //打开pack1定义的demo_cursor的游标
    end;  //over
    

    ----------java调用部分--------------------
package com.luowen.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

public class Test {
	public static void main(String[] args) {
		getPage("emp",5,1);
		
	}
	private static void getPage(String tabName,int start,int end) {
		ResultSet  rs = null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl","scott","tiger");
			String sql = "{call pro_demo(?,?,?,?,?,?)}";
			CallableStatement  cs = ct.prepareCall(sql);
			cs.setString(1, tabName);
			cs.setInt(2,start);
			cs.setInt(3,end);
			cs.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR);
			cs.registerOutParameter(5, oracle.jdbc.OracleTypes.NUMBER);
			cs.registerOutParameter(6, oracle.jdbc.OracleTypes.NUMBER);
			cs.execute();
			rs = (ResultSet) cs.getObject(4);
			int cnt = cs.getInt(5);
			int page_cnt = cs.getInt(6);
			while(rs.next()){
				System.out.println(rs.getObject(3) + "---" + rs.getObject(4) + "---" + rs.getObject(9));
			}
			System.out.println("总的数据:"+cnt+"共有页数:"+page_cnt);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally{
			if(rs != null){
				try {
					rs.close();
				} catch (Exception e2) {
					// TODO: handle exception
					e2.printStackTrace();
				}
			}
		}
	}
}
    

Oracle视图
    create view view_name as select 语句 [with read only]  --//带上with read only 表示只能读,不能删除,添加
    drop view view_name;      //删除视图

Oracle 触发器
    1.dml触发器(数据操作语言,insert,delete,update);
    2.ddl触发器(数据定义语言,create table,create view ,create tigger,drop)
    3.系统触发器 (与系统相关的触发器,比如用户登入,退出,启动数据库,关闭数据库)

    create trigger my_trigger
    after insert on scott.emp
    begin
    dbms_output.put_line('添加了一条数据')
    end;

    create or replace my_trigger
    after update on scott.emp
    for each row ------//每行变化都监听,打印下面的数据
    begin
        dbms_output.put_line('更新了一条数'');
    end;

    create or replace my_trigger
    after delete on scott.emp for each row
    begin
       if to_char(sysdate,'day') in ('星期六','星期天') then
           dbms_output.put_line('周末不能删除数据');
           RAISE_APPLICATION_ERROR(-20001,'周末不能删除数据');  ---//抛出一个异常,用于阻止用户删除数据
       end if;
    end;
    ---//注:RAISE_APPLICATION_ERROR 填入两个参数 -20000 ~ -20999,自定义错误语句

    create or replace tigger trig2
    before
    insert or update or delete on  ---//监听多个事件,insert,update,delete
    scott.emp
    begin
    case
        when inserting then
            dbms_output.put_line('insertint');
        when udating then
            dbms_output.put_line('updating');
        when deleteing then
            dbms_output.put_line('delete');
    end case;
    end;

    create or replace trigger trig3
    after update on scott.emp for each row
    begin
        if :new.sal < :old.sal then
            dbms_output.put_line('工资不能减少');
        end if;
    end;

Oracle系统触发器
    create or replace trigger 触发器名字
    after [before] logon [logoff] on databases
    begin
        ---//执行语句
    end;

    eg.
        //用户登入记录数据
        create or replace trigger tri1
        after logon or logoff on database
        begin
            insert into log_table (username,login_time,ip) values(ora_login_user,sysdate,ora_client_ip_address);
        end;
    //用户退出记录信息
    create or replace trigger tri2
        before logoff on database
            begin
                insert into login_table (username,logout_time,ip) values (ora_login_user,sysdate,ora_client_ip_address);
    end;
*/

  

原文地址:https://www.cnblogs.com/luowen/p/3457441.html