zoukankan      html  css  js  c++  java
  • SQL server与Oracle触发器的创建与使用

    SQL Server

    1创建触发器

    GO
    BEGIN
    IF (object_id('WMY', 'tr') is not null)
    DROP trigger WMY
    END;
    GO
    CREATE TRIGGER WMY
    ON Student
    Instead of INSERT
    AS
    BEGIN
        INSERT INTO Student (number,name) VALUES (1205,'角色2');
    END;
    --Begin 与end相当于{},是一个语句块,可有可无此处为演示所用
    --ON 后面跟表明,表示作用于那个表
    --ON Student下面(Instead of INSERT)可有改为(Instead of,after,for)(update,delete,Insert)
    

    解析(以上列Insert触发器为例其他雷同)(以下先后顺序以插入表中数据的排序为例)

    • 当为Instead of 时,在触发器中的SQL语句代替你文中执行的插入语句,即当你在任何地方执行一个插入语句,这条语句实际没有执行而触发器里面的语句则执行
    • 当为for 时,在触发器中的SQL语句与你文中执行的插入语句都执行只是触发器中先于文中的执行
    • 当为 After时 在触发器中的SQL语句与你文中执行的插入语句都执行只是触发器中晚于文中的执行(网上都这样说可简单测试时与for效果一样)

    摘自网上:

    1 “Instead of”触发器

    • “Instead of”触发器在执行真正“插入”之前被执行。除表之外,“Instead of” 触发器也可以用于视图,用来扩展视图可以支持的更新操作。
    • “Instead of”触发器会替代所要执行的SQL语句,言下之意就是所要执行SQL并不会“真正执行”

    2 “After”触发器

    • “After”触发器在Insert、Update或Deleted语句执行之后被触发。“After”触发器只能用于表。
    • “After”触发器主要用于表在修改后(insert、update或delete操作之后),来修改其他表

    SQL Server为每个触发器都创建了两个专用表:Inserted表和Deleted表

    • 这两个表由系统来维护,它们存在于内存中而不是在数据库中,可以理解为一个虚拟的表。
    • 这两个表的结构总是与被该触发器作用的表的结构相同。
    • 触发器执行完成后,与该触发器相关的这两个表也被删除。
    • Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。
    • Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。
    GO
    INSERT INTO Student (number,name) VALUES (1807,'角色');
    

    深度解析使用序列以及Inserted表

    USE [OSMP]
    BEGIN
    IF EXISTS (SELECT * FROM sysobjects WHERE name = 'Person')
    AND NOT EXISTS (select * from Person) --这条语句的意思是当表存在并且不为空是执行下面的语句 ,and对应&&,or 对应||
    DROP table Person
    END
    GO
    CREATE TABLE Person
    (
        num int,
        S_score int,
        S_name NVARCHAR(64),
        primary key (num)
    )
    BEGIN
    IF EXISTS (SELECT * FROM sysobjects WHERE name = 'Student')
    AND NOT EXISTS (select * from Student) 
    DROP table Student
    END
    GO
    CREATE TABLE Student
    (
        score int,
        name NVARCHAR(64),
        primary key (name)
    )
    --创建序列
    BEGIN
    IF EXISTS (SELECT * FROM sysobjects WHERE name = 'Student_SEQ')
    DROP SEQUENCE Student_SEQ
    END
    CREATE SEQUENCE Student_SEQ
    MINVALUE 1
    MAXVALUE 999999999999
    START WITH 1
    INCREMENT BY 1
    CACHE 20;
    
    GO
    BEGIN
    IF (object_id('WMY', 'tr') is not null)
    DROP trigger WMY
    END;
    GO
    CREATE TRIGGER WMY
    ON Student
    instead of INSERT
    AS
    BEGIN
        Insert into Person (num,S_score,S_name)select next value for Student_SEQ,score,name from Inserted 
        --Insert into Person (num,S_score,S_name)select next value for Student_SEQ,a.* from Inserted a --简化写法
    --Insert into Person select next value for Student_SEQ,* from Inserted
        --此处并无意思主要用于理解,执行下面的Student插入语句是,数据库维护了一个与Student数据结构一样的表Inserted,
    --这里利用这个表和序列值来为Person做插入,而实际上没有执行Student插入,如果想要Student也执行把Instead of 改为for或after END; GO Insert into Student(score,name) values('1','m');

    插曲获取序列的当前值

    GO
    SELECT current_value FROM sys.sequences WHERE name = 'Student_SEQ'
    

    sql server定义变量以及变量赋值

    DECLARE @index VARCHAR(20),@Orderindex VARCHAR(20);
    select @index=next value for ENTITY_SEQ;
    select @Orderindex= 'R_'+rtrim(ltrim(right(cast('00000000'+rtrim(cast(@index as int)) as varchar(20)),10)))
    

      

    Oracle 触发器与SQL server类似,在此只显示代码

    new是新插入的数据,old是原来的数据
    
    insert只会有new,代表着要插入的新记录
    
    delete只会有old,代表着要删除的记录
    
    update由于执行的是先删除旧的记录,再插入新的记录,因此new和old都会有,且含义与上面的相同
    
    注:update触发器,可根据具体需求选择记录旧记录还是新记录。

      *这两个变量只有在使用了关键字 "FOR EACH ROW"时才存在.且update语句两个都有,而insert只有:new ,delect 只有:old;

      * for each row 指定触发器每行触发一次

    BEGIN
        EXECUTE IMMEDIATE 'DROP TABLE Person';
        EXCEPTION WHEN OTHERS THEN NULL;
    END;
    
    CREATE TABLE Person
    (
        num        INTEGER
        S_score   INTEGER,
        S_name     NVARCHAR2(64),
        primary key (num)
    )
    BEGIN
        EXECUTE IMMEDIATE 'DROP TABLE Student';
        EXCEPTION WHEN OTHERS THEN NULL;
    END;
    
    CREATE TABLE Student
    (
        score   INTEGER,
        name     NVARCHAR2(64),
        primary key (name)
    )
    --创建序列
    BEGIN
        EXECUTE IMMEDIATE 'DROP SEQUENCE Student_SEQ';
        EXCEPTION WHEN OTHERS THEN NULL;
    END;
    CREATE SEQUENCE Student_SEQ
    MINVALUE 1
    MAXVALUE 999999999999999999999999999
    START WITH 1
    INCREMENT BY 1
    CACHE 20;
    CREATE OR REPLACE TRIGGER TR_INST_DEVICE
    BEFORE INSERT ON M_DEVICEENTITY
    FOR EACH ROW
    
    BEGIN
        select Student_SEQ.NEXTVAL into :new.num from dual;
        --select 'A' || trim(to_char(:new.num, '00000000')) into :new.score from dual;
        --这个两语句作用并无练习,第一个取出序列的下一个值插入new表中(new表类似SQL server 中的Inserted)
        --更改score的标示发以A_0000001为样式,这个语句只做参考在此处无用也运行不了(因为表的字段类型)
    END;
    GO
    Insert into Student(score,name) values('1','m')

     Intert into Select值与表组合的表示方法

    Insert into Person(n, num, name) select next value for ENTITY_SEQ,number,name from Student where number=114;
    --next value for ENTITY_SEQ序列与select字段组合添加
    Insert into Person(n, num, name) select cast(100 as int),number,name from Student where number=114;
    --cast(100 as int)值与字段组合添加

     C# 中Oracle分页写法 end,start为传入的数值,

     cmd.CommandText = @"SELECT * FROM (SELECT ROWNUM AS rowno, t.*  FROM  '+tablename +' t
                     WHERE ROWNUM <=  '" + end + "') table_alias  WHERE table_alias.rowno >=  '" + start + "'";

     

       cmd.CommandText = @"select * from M_ORDERHANDLE where ORDERINDEX  = '" + orderindex + "'";  
    

      

    SELECT *
      FROM (SELECT ROWNUM AS rowno, t.*
              FROM emp t
             WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')
                                 AND TO_DATE ('20060731', 'yyyymmdd')
               AND ROWNUM <= 20) table_alias
     WHERE table_alias.rowno >= 10;
    

      

    SELECT * FROM (SELECT * FROM M_ALARM ) WHERE ROWNUM <=500  ORDER BY ROWNUM Desc;
    

      

    --Oracle环境下的时间比对语句
    SELECT * FROM M_WORKORDER where CREATETIME  >= to_date('2015/03/23','yyyy-mm-dd hh24:mi:ss') and
    CREATETIME <= to_date('2016/03/23','yyyy-mm-dd hh24:mi:ss') SELECT * FROM M_WORKORDER where to_char(CREATETIME, 'yyyy-mm-dd hh24:mi:ss') >= '2015-03-01 00:00:00' and
    to_char(CREATETIME, 'yyyy-mm-dd hh24:mi:ss') <= '2016-04-05 00:00:00' --注意时间格式转换为一致

      

    //Oracle多表连接查询
    string sql =  @"SELECT W.*, D.*, AH.*, A.ALARMDESCRIPTION, A.DETECTTIME, A.ALARMPHENOMENON, A.ENTITYTYPE
                                FROM  M_WORKORDER W, M_ALARM A,
                                (SELECT * FROM
                                    (SELECT ROW_NUMBER() OVER (PARTITION BY H.ALARMINDEX ORDER BY H.HANDLETIME DESC) N,
                                    H.* FROM M_ALARMHANDLE H)
                                WHERE N = 1) AH,
                                (SELECT * FROM M_CONFIGITEMRELATION C, M_BUSINESSENTITY B 
                                WHERE C.TARGETINDEX = B.ENTITYINDEX AND C.GROUPTYPE = 1) D 
                                WHERE W.ALARMINDEX = D.SOURCEINDEX(+) AND W.ALARMINDEX = AH.ALARMINDEX(+) AND
                                A.ALARMINDEX = W.ALARMINDEX AND 
    to_char(CREATETIME, 'yyyy-mm-dd') >= '" + Convert.ToDateTime(StartTime).ToString("yyyy-MM-dd") + "' and
    to_char(CREATETIME, 'yyyy-mm-dd') <= '" + Convert.ToDateTime(EndTime).ToString("yyyy-MM-dd") + "' and rownum<20";

      注意 (+)左右边对应的是左右连接,

    //SQL server 对应的多表连接查询
    string sql = @"SELECT W.*, D.*, AH.*, A.ALARMDESCRIPTION, A.DETECTTIME, A.ALARMPHENOMENON, A.ENTITYTYPE
                                FROM  M_ALARM A,M_WORKORDER W LEFT JOIN
                                (SELECT * FROM 
                                  (SELECT ROW_NUMBER() OVER (PARTITION BY H.ALARMINDEX ORDER BY H.HANDLETIME DESC) N,
                                    H.* FROM M_ALARMHANDLE H) M
                                WHERE M.N=1)AH on W.ALARMINDEX = AH.ALARMINDEX  
    							   LEFT JOIN
                                (SELECT * FROM M_CONFIGITEMRELATION C, M_BUSINESSENTITY B 
                                WHERE C.TARGETINDEX = B.ENTITYINDEX AND C.GROUPTYPE = 1)D ON W.ALARMINDEX = D.SOURCEINDEX
                                WHERE A.ALARMINDEX = W.ALARMINDEX and CONVERT(varchar(100),w.createtime, 20) >= '" +
    Convert.ToDateTime(StartTime).ToString("yyyy-MM-dd") + "' and
    CONVERT(varchar(100),w.createtime, 20) <= '" + Convert.ToDateTime(EndTime).ToString("yyyy-MM-dd") + "'";

    SQL server Select Into用法详解

    http://wenku.baidu.com/link?url=I7DrdMzq7-ONDePwrmkHJjofYiS1KL6kyT9pzVcLvz4g0eSxoKH0lvfJYtEcJhxgsfVrB9uHokJRHjHC43kj6sxN5bVCQUoSh-B-IB5tQHC

    SQL server 触发器里面判断是什么引发的触发

    http://www.2cto.com/database/201308/238647.html

     

  • 相关阅读:
    JavaScript prototype应用
    HTML表格
    ramnit病毒
    HTML简历表格
    Oracle、SQL Server、MySQL数据类型对比
    Oracle、SQL Server、MySQL分页方法
    java操作数据库出错
    SQL基本CRUD
    Oracle基础函数
    SQL多表查询
  • 原文地址:https://www.cnblogs.com/wangboke/p/5502293.html
Copyright © 2011-2022 走看看