-- 触发E器
-- 案例1 禁止用户插入新的记录CREATE TRIGGER no_insertON xsAFTER INSERT -- 在Insert只有才发生吗? 那么ASBEGINRAISERROR('XS表不允许插入新的记录',1,1); --返回信息,这是个INSERT 后放弃的过程ROLLBACK TRANSACTIONENDSELECT * FROM inserted
SELECT *
FROM XSINSERT INTO XS
VALUES('14311101','SOAR','女','1977-10-11','14信管','江西萍乡','18','');DELETE XS
WHERE 姓名='SOAR';DROP TRIGGER no_insert;
-- 案例2 DELETE 的触发器,作用是删除数据后给出提示CREATE TRIGGER xs_delON XSAFTER DELETEASBEGIN SELECT 学号 as '被删除的学生',姓名 FROM deletedENDDELETE FROM XS WHERE 学号='14311101';
DROP TRIGGER xs_del; -- UPDATE 触发器CREATE TRIGGER xs_update
ON XSAFTER UPDATEASBEGIN SELECT 姓名 AS '更改后',学号 FROM inserted; -- 这里可以看出更新的系统逻辑 SELECT 姓名 AS '更改前',学号 FROM deletedENDUPDATE XS SET 姓名='SOAR'
WHERE 学号='14311002'UPDATE XS SET 姓名='贺梅'
WHERE 学号='14311002'DROP TRIGGER xs_update
-- INSEAD OF 触发器
-- 对比一下不让INSERT的过程CREATE TRIGGER xs_instead
ON xsINSTEAD OF INSERTASBEGIN DECLARE @st INT; SELECT @st = (SELECT 总学分 FROM inserted) IF @st >30 SELECT '总学分不符合要求' AS 失败原因ENDINSERT INTO XS(学号,姓名,总学分) VALUES('15001','张三','35');
SELECT * FROM XS WHERE 学号='15001';
-- 针对整个数据库的触发器CREATE TRIGGER saftyON DATABASE -- ALL SERVER 这个是要求对所有数据库生效的,我认为没事的话,不会有人去写这个的FOR DROP_TABLE,ALTER_TABLEASBEGIN PRINT '当前数据库禁止更新删除操作' ROLLBACK TRANSACTIONENDDROP TRIGGER safty;
DROP TABLE XS;
-- 创建一个登陆触发器 这个不好测试,因为是针对IP地址的验证-- 创建一个触发器当登陆名为test 的时候,只允许在8:00 - 17:30 的时间登陆
CREATE TRIGGER time_limit
ON ALL SERVER WITH EXECUTE AS 'log_test'FOR LOGONASBEGINIF ORIGINAL_LOGIN()='log_test' AND CONVERT(CHAR(10),GETDATE(),108) BETWEEN '08:00:00' AND '10:30:00'ROLLBACK;ENDSELECT CONVERT(CHAR(10),GETDATE(),108)
DROP TRIGGER time_limit;
-- 首先创建一个用户,命名为test
-- 针对不同级别的触发器,查看的地方不同,表级别、数据库级别、服务器级别
-- 注意一下权限的部分
-- 限制对保护数据的操作
CREATE TRIGGER update_limit ON XSFOR updateASBEGINIF update(班级) and Exists(SELECT * FROM inserted WHERE 学号='14311002')RAISERROR('学号为1431102学生的班级不能修改',16,1)ROLLBACK TRANSACTIONEND;SELECT * FROM XS WHERE 学号='14311002'
update xs set 班级='19计科' WHERE 学号='14311002' ;
-- 触发器实现级联操作
-- 使用触发器对有关系的表进行级联操作,比如级联更新\级联删除CREATE TRIGGER trigdelete
ON xsAFTER DELETEASBEGIN DELETE XK WHERE 学号=(SELECT 学号 FROM deleted)END-- 所谓的更新就是插入和删除的概念
SELECT * FROM XS INNER JOIN XK ON XS.学号=XK.学号SELECT * FROM XK
DELETE FROM XS WHERE 学号='14311001' ; -- 这里可以实践一下DELETE的动作
-- 修改触发器
-- 使用系统存储过程查看触发器
SP_HELPTEXT UPDATE_LIMIT;EXEC sp_rename update_limit,update_test; -- OK
-- 禁止触发器的两种写法
ALTER TABLE XS
DISABLE TRIGGER update_test; --会有一个打叉的情况DISABLE TRIGGER update_test ON xs;
-- 启用触发器ALTER TABLE xs
ENABLE TRIGGER no_insert;-- 这种触发器常用于记录删除数据,但是呢,要针对指定的列进行删除,否则不能记录
-- 索引-- 索引会占据空间, 对数据的增删和修改,都会影响到索引的空间
-- 如何查看索引的空间情况
-- 索引包括聚集索引,非聚集索引,全文索引,XML索引和空间索引5种主要类型
-- 聚集索引,非聚集索引 ,
-- 聚集索引,每张表只能有一个,而非聚集索引可以有多个
-- 创建索引的几种方式
CREATE Clustered Index IX_XS_name
ON XS(姓名) -- 会报错CREATE Unique nonClustered Index IX_XS_number
ON XS(学号)With IGNORE_DUP_KEY-- 查看索引
EXEC sp_helpindex XS-- 重建索引 ALL 表示所有索引重建
Alter Index ALL ON XS Rebuild--
Alter Index IX_XS_number ON XS RebuildDrop Index XS.IX_XS_number
-- 索引预留空间
CREATE UNIQUE NONCLUSTERED INDEX IX_XS_numberON XS(学号)WITH (PAD_INDEX=ON,FILLFACTOR=10) -- 索引的分析-- SHOWPLAN_ALL 语句USE xsxk
GOSET SHOWPLAN_ALL ONGOSELECT 学号,姓名,性别,出生日期FROM XS WHERE 出生日期>='1995-10-1'AND 出生日期 <='1995-10-30'GOSET SHOWPLAN_ALL OFF USE xsxkGOSET STATISTICS IO ON GOSELECT 学号,姓名,性别,出生日期FROM XS WHERE 出生日期>='1995-10-1'AND 出生日期 <='1995-10-30'GOSET STATISTICS IO OFF -- 获取索引中的平均碎片USE xsxk
GOSELECT avg_fragmentation_in_percentFROM sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID('XS'),NULL,NULL,NULL) -- 全文索引-- 全文索引的意义在哪里?