`
hgq0011
  • 浏览: 540670 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

触发器--用来获取那写字段更新

阅读更多

在网上找到了一个类似的文章http://www.cnblogs.com/delphi/articles/121516.html来引用这文章.我在它的基础上加了更详细注解。  如下:          

CREATE Table T_Test (
f_id    
int IDENTITY(11Primary Key,
f_char    
Char(8default '',
f_varchar   
varchar(8default '',
f_nvarchar   
nvarchar(8default '',
f_datetime   
datetime default getdate(),
f_int    
int default 0,
f_bigint   
bigint default 0,
f_decimal   
decimal(186default 0.00,
f_number   numeric(
186default 0.00,
f_float    
float default 0.00
)
go

INSERT INTO T_Test (f_char) values('001')
INSERT INTO T_Test (f_char) values('002')
go

select * from t_test



If exists(select * from sysobjects where id=object_id(N'[dbo].[Tri_Test_Upd]'and objectproperty(id,N'istrigger')=1)  
   
DROP TRIGGER Tri_Test_Upd  
go  
 
CREATE TRIGGER Tri_Test_Upd ON T_Test --WITH ENCRYPTION  
FOR UPDATE  
AS  


DECLARE @iRowCnt INT  --列数
 
SET @iRowCnt = @@rowcount  
 
IF @iRowCnt < 1  
RETURN  
 
DECLARE  
 
@sTable  VARCHAR(128),  --表名
 @sPKName VARCHAR(32),  --主鍵名
 @sColName VARCHAR(128)  --列名
 
DECLARE  
 
@iColCnt  INT,  --列数
 @iColId  INT  --列id
 
DECLARE  
 
@i    TINYINT,  
 
@j    TINYINT,  
 
@iSegment TINYINT,  --以8为除数得余数(有少个分段)
 @iVal   TINYINT,  --被更新过的字段的十六进制值
 @iLog2  TINYINT  
 
DECLARE  
 
@sSQL  VARCHAR(8000)  --执行的sql
 
SET @sTable = 't_test'  
SET @sPKName = 'f_id'  
 
-- 求得当前表列个数  
SELECT @iColCnt = Count(1FROM syscolumns WHERE id = object_id(@sTable)  
 
-- 以8个字段为一小段  
SET @iSegment = CASE  
      
WHEN @iColCnt / 8 = @iColCnt / 8.0  --如果列总数是8的倍数那就取整数,否则取整数再加1
       THEN  
        
@iColCnt / 8  
       
ELSE  
        
@iColCnt / 8 + 1  
       
END  
-- 将数据存入临时表
SELECT * INTO #Inserted FROM Inserted  --更新的数据
SELECT * INTO #Deleted FROM Deleted  --更新前的数据
 
--中间处理数据用
CREATE TABLE #Temp(  
  f_PKVal  
varchar(254not null primary key,  --主键
  f_OldVal  varchar(254),  --原来的值
  f_NewVal  varchar(254)  --新的值
)  
 
SET @i = 0  --循环整个分段(也就所有的字段)
 
WHILE @i < @iSegment  
  
BEGIN  
 
--8个字段为一个分区,当表的列数大于8,那么计算被更新过的字段的十六进制值方法不同
 IF @iColCnt < 9  --表的列数小于8
   SET @iVal= COLUMNS_UPDATED()  
 
ELSE  --表的列数大于8
   SET @iVal= SubString(COLUMNS_UPDATED(), @i + 11)  
  
 
--等于零,则表示当前小节所对应的8个字段没有被更新(修改)过,中止本次循环,继续下一次循环
 IF @iVal = 0  
  
BEGIN  
    
SET @i = @i + 1  
    
CONTINUE  
  
END  
  
 
WHILE @iVal > 0  
  
BEGIN  
   
SET @j = 0  
   
SET @iLog2 = @iVal / 2  --被更新字段十六进制值除2得余数
  
   
WHILE @iLog2 > 0  
    
BEGIN  
     
SET @j = @j + 1  
     
SET @iLog2 = @iLog2 / 2  
    
END --end @iLog2 > 0 
  
    
-- 得到被Update 的 列ID  
    SET @iColId = 8 * @i + @j + 1  
  
    
-- 将Update列名 赋予 @sColName  
    SELECT @sColName = S.name FROM Inserted as I,Deleted as D,Syscolumns as S WHERE I.F_id = D.F_id  
    
AND S.id = object_id(@sTable)  
    
AND S.colid = @iColId  
  
    
Truncate table #Temp  
    
--拼成功能语句
    SET @sSQL = 'INSERT INTO #Temp (f_PkVal, f_OldVal, f_NewVal) ' +  
       
'SELECT Convert( varchar(200), I.' + @sPkName + '), ' +  
       
'Convert( varchar(200), D.' + @sColName + '), ' +  
       
'Convert( varchar(200), I.' + @sColName + '' +  
       
'FROM  #Inserted as I, #Deleted as D ' +  
       
'WHERE I.' + @sPKName + ' = D.' + @sPKName +  
       
' AND I.' + @sColName + ' <> D.' + @sColName  
  
    
EXEC(@sSQL--执行sql 
  
    
-- 测试输出
    Select f_pkVal,  @sColName as f_column_name, f_oldVal, f_newVal  FROM #temp  
    
-- 实际上用将信息处理后插入消息表
    /**//**//**//*  
    ..  
     
    INSERT INTO T_Message(.)  
    SELECT 要组成的内容
    FROM #temp  
    
*/
  
  
    
SET @iVal = @iVal - Power(2@j)  
  
END -- end  @iVal > 0
 SET @i = @i + 1  
   
END -- end @i < @iSegment
 
DROP TABLE #Inserted  
DROP TABLE #Deleted  
DROP TABLE #Temp  
 
go  


select from Syscolumns as S object_id('t_test')
SELECT  s.name ,s.colid FROM syscolumns as s WHERE id = object_id('t_test')  and s.colid = 1

Update T_test Set f_datetime = getdate(), f_float = 0.0123, f_int= 1  where f_id = 2


这样还真行,很高兴又学到了一招,:)这样很有意思,也有挑战性。

基礎知識:
COLUMNS_UPDATED()是一個僅可在 Insert or Update trigger 中調用的方法.
該方法返回 一個 varbinary 的值, 存儲了當次Insert 或是 Update 觸發器所對應的記錄在哪些字段上發生了Inserted or updated.在SQLSERVER 的聯機幫助[CREATE TRIGGER]和[IF UPDATE] 中 有對 COLUMNS_UPDATED () 方法的簡要描述.

分享到:
评论

相关推荐

    精髓Oralcle讲课笔记

    --求那些人的薪水是在平均薪水之上的。 61、select ename, sal from emp join (select max(sal) max_sal ,deptno from emp group by deptno) t on (emp.sal = t.max_sal and emp.deptno=t.deptno); --查询每个...

    数据库设计经验谈.pdf

    9 保持字段名和类型的一致性 9 仔细选择数字类型 9 删除标记 10 避免使用触发器 10 包含版本机制 10 给文本字段留足余量 10 列[字段]命名技巧 10 第 3 部分 - 选择键和索引 11 数据采掘要预先计划 11 使用系统生成的...

    hibernate 框架详解

    触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. ...

    最全Hibernate 参考文档

    16.4. 定制SQL用来create,update和delete 16.5. 定制装载SQL 17. 过滤数据 17.1. Hibernate 过滤器(filters) 18. XML映射 18.1. 用XML数据进行工作 18.1.1. 指定同时映射XML和类 18.1.2. 只定义XML映射 18.2. XML...

    hibernate3.04中文文档.chm

    17.4. 定制SQL用来create,update和delete 17.5. 定制装载SQL 18. 过滤数据 18.1. Hibernate 过滤器(filters) 19. XML映射 19.1. 用XML数据进行工作 19.1.1. 指定同时映射XML和类 19.1.2. 只定义XML映射 ...

    Hibernate3+中文参考文档

    16.4. 定制SQL用来create,update和delete 16.5. 定制装载SQL 17. 过滤数据 17.1. Hibernate 过滤器(filters) 18. XML映射 18.1. 用XML数据进行工作 18.1.1. 指定同时映射XML和类 18.1.2. 只定义XML映射 18.2. XML...

    Hibernate教程

    17.4. 定制SQL用来create,update和delete 17.5. 定制装载SQL 18. 过滤数据 18.1. Hibernate 过滤器(filters) 19. XML映射 19.1. 用XML数据进行工作 19.1.1. 指定同时映射XML和类 19.1.2. 只定义XML映射 19.2. ...

    hibernate 体系结构与配置 参考文档(html)

    触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (可选) 5.1.9. property 5.1.10. 多对...

    Hibernate参考文档

    16.3. 定制SQL用来create,update和delete 16.4. 定制装载SQL 17. 过滤数据 17.1. Hibernate 过滤器(filters) 18. XML映射 18.1. 用XML数据进行工作 18.1.1. 指定同时映射XML和类 18.1.2. 只定义XML映射 18.2. XML...

    Hibernate 中文 html 帮助文档

    16.3. 定制SQL用来create,update和delete 16.4. 定制装载SQL 17. 过滤数据 17.1. Hibernate 过滤器(filters) 18. XML映射 18.1. 用XML数据进行工作 18.1.1. 指定同时映射XML和类 18.1.2. 只定义XML映射 18.2. XML...

    PL/SQL Developer8.04官网程序_keygen_汉化

     可配置的树形浏览能够显示同PL/SQL开发相关的全部信息,使用该浏览器可以获取对象描述、浏览对象定义、创建测试脚本以便调试、使能或禁止触发器或约束条件、重新编译不合法对象、查询或编辑表格、浏览数据、在对象...

    PLSQLDeveloper下载

    对象浏览器——可配置的树形浏览能够显示同PL/SQL开发相关的全部信息,使用该浏览器可以获取对象描述、浏览对象定义、创建测试脚本以便调试、使能或禁止触发器或约束条件、重新编译不合法对象、查询或编辑表格、...

Global site tag (gtag.js) - Google Analytics