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用法详解
SQL server 触发器里面判断是什么引发的触发
http://www.2cto.com/database/201308/238647.html