Sql server 2008 触发器实现

昨天在进行系统升级中,对于某些程序生成的中间表数据的矫正的工作十分恼火。因现场采集设备和计量设备运行情况及变更情况不可控。常常造成因非程序因素(自定义名词,大概的意思就是因为现场采集设备断电、计量设备更换、系统基础通讯信息发生变更等一系列认为原因影响数据存储的准确性),影响后期的数据统计分析的准确性和有效性。不时被客户发现直接向市场部投诉说系统不稳定,要求现场排查问题。我擦!牢骚终止。

终究其问题主要是在生成中间表时,没有必要的验证。只是单纯的在某项操作中,添加的生成中间表的响应操作。后期当发现中间表中存在某些影响统计的信息(如按日统计用量,在中间表的却存在夸天的信息描述)。为了完善该内容,曾经尝试创建定时作业,对于中间表进行扫描,将影响统计分析的信息进行自动处理。问题数据还是会有一段时间存储在数据表中,总觉得存在一定的隐患。所以就像开篇的标题,对于生成中间表中数据有效性、规范性,在牺牲更新效率的前提下创建触发器,当计量数据表发生更新操作后,通过触发器自动向中间表进行操作。

create trigger trigger_name           
on {table_name | view_name}    --   触发器操作对象 可以是数据表 或视图   
{for After | Instead of }      --   触发器类型      
[ insert, update,delete ]      --   什么情况激活触发器     
as            
   sql_statement               --   触发器操作

这里重点强调一下触发器类型,主要分为两种After和Instead of。after 只能绑定到数据表,是在插入、更新、删除操作发生后,激活该触发器。Instead of 从英文直译过来是替代,理解上就是在进行插入、更新、删除发生前,激活该触发器。其能绑定到数据表或者视图。

来一个实例看一下:这里为after类型的触发器,当绑定数据表发生更新操作时触发。触发结果为向中间表添加信息。并加载了数据规范验证。

-----创建MeterReadingData 的T_HouseRealtimeD 数据表 Update 触发器
if (object_id(‘tgr_classes_UpdateHouseRealtimeD‘, ‘TR‘) is not null)
    drop trigger tgr_classes_UpdateHouseRealtimeD
go
create trigger	tgr_classes_UpdateHouseRealtimeD
on
	Db_MeterReadingData.dbo.T_HouseRealtimeD
for update
as
	begin
		set nocount on
		--创建旧的仪表数据
		declare
			@HRD_MeterNum nvarchar(50),
			@HDI_StartHeatNum  decimal(18,2),
			@HDI_EndHeatNum  decimal(18,2),
			@HDI_RunTimeInterval int,
			@HDI_RunTimeIntervalStart int,
			@HDI_RunTimeIntervalEnd int,
			@HDI_StartTime datetime,
			@HDI_EndTime datetime,
			@HDI_AvgEntryTemp decimal(18,2),
			@HDI_AvgEntryTempStart decimal(18,2),
			@HDI_AvgEntryTempEnd decimal(18,2),
			@HDI_AvgExportTemp decimal(18,2),
			@HDI_AvgExportTempStart decimal(18,2),
			@HDI_AvgExportTempEnd decimal(18,2),
			@HDI_FluxUsed decimal(18,2),
			@HDI_FluxUsedStart decimal(18,2),
			@HDI_FluxUsedend decimal(18,2)
		--select 
		--	HRD_MeterNum,
		--	hrd_cumHeat,
		--	hrd_runtime,
		--	hrd_collecttime,
		--	hrd_EntryTemp,
		--	hrd_ExportTemp,
		--	hrd_cumFlux
		--from
		--	deleted

		--select 
		--	hrd_cumHeat,
		--	hrd_runtime,
		--	hrd_EntryTemp,
		--	hrd_ExportTemp,
		--	hrd_cumFlux,
		--	hrd_collecttime
		--from
		--	inserted

		insert into Db_MeterReadingData.dbo.T_MeterUseHeatingDetailInformation
		(
			HRD_ID,
			HRD_MeterNum,
			HDI_StartHeatNum,
			HDI_EndHeatNum,
			HDI_RunTimeInterval,
			HDI_StartTime,
			HDI_EndTime,
			HDI_AvgEntryTemp,
			HDI_AvgExportTemp,
			HDI_FluxUsed,
			HDI_isSettlement
		)
		select
			0,
			inserted.HRD_MeterNum,
			deleted.hrd_cumHeat,
			inserted.hrd_cumHeat,
			(inserted.hrd_runtime-deleted.hrd_runtime),
			deleted.hrd_collecttime,
			inserted.hrd_collecttime,
			(inserted.hrd_EntryTemp+deleted.hrd_EntryTemp)/case when datediff(hour,deleted.hrd_collecttime,
			inserted.hrd_collecttime)>0 then datediff(hour,deleted.hrd_collecttime,
			inserted.hrd_collecttime) else 1 end,
			(inserted.hrd_ExportTemp+deleted.hrd_ExportTemp)/case when datediff(hour,deleted.hrd_collecttime,
			inserted.hrd_collecttime)>0 then datediff(hour,deleted.hrd_collecttime,
			inserted.hrd_collecttime) else 1 end,
			(inserted.hrd_cumFlux-deleted.hrd_cumFlux),
			0
		from
			deleted inner join inserted
		on
			deleted.HRD_MeterNum=inserted.HRD_MeterNum
		where
			datediff(hour,deleted.hrd_collecttime,inserted.hrd_collecttime)<=1

		if exists(select
			1
		from
			deleted inner join inserted
		on
			deleted.HRD_MeterNum=inserted.HRD_MeterNum
		where
			datediff(hour,deleted.hrd_collecttime,inserted.hrd_collecttime)>1)
	begin
		declare @StartTime datetime,@EndTime datetime

		declare @MeterTableID table
		(
			--HDI_ID int,
			MeterID nvarchar(50),
			StartHeatNum decimal(18,2),
			EndHeatNum decimal(18,2),
			runTime int,
			avgEntryTemp decimal(18,2),
			avgExportTemp decimal(18,2), 
			fluxUsed decimal(18,2),
			startTime datetime,
			endTime datetime
		)
		---init parameter
		--select @StartTime=‘2014-02-06 19:00:00‘,@EndTime=‘2014-02-08 16:00:00‘

		insert into @MeterTableID
		select
			inserted.HRD_MeterNum,
			deleted.hrd_cumHeat,
			inserted.hrd_cumHeat,
			(inserted.hrd_runtime-deleted.hrd_runtime),
			(inserted.hrd_EntryTemp+deleted.hrd_EntryTemp)/case when datediff(hour,deleted.hrd_collecttime,
			inserted.hrd_collecttime)>0 then datediff(hour,deleted.hrd_collecttime,
			inserted.hrd_collecttime) else 1 end,
			(inserted.hrd_ExportTemp+deleted.hrd_ExportTemp)/case when datediff(hour,deleted.hrd_collecttime,
			inserted.hrd_collecttime)>0 then datediff(hour,deleted.hrd_collecttime,
			inserted.hrd_collecttime) else 1 end,
			(inserted.hrd_cumFlux-deleted.hrd_cumFlux),
			deleted.hrd_collecttime,
			inserted.hrd_collecttime
		from
			deleted inner join inserted
		on
			deleted.HRD_MeterNum=inserted.HRD_MeterNum
		where
			datediff(hour,deleted.hrd_collecttime,inserted.hrd_collecttime)<=1
	    
	    
		--select M_ID from Db_MeterReadingSys.dbo.T_MeterInformation
		---init End

		declare @Count int,@Count_Temp int

		declare Temp_Main cursor for
		select 
			MeterID ,
			StartHeatNum,
			EndHeatNum ,
			runTime,
			avgEntryTemp ,
			avgExportTemp ,
			fluxUsed ,
			startTime,
			endTime
		from @MeterTableID

		declare 	

			@MeterID nvarchar(50),
			@StartHeatNum decimal(18,2),
			@EndHeatNum decimal(18,2),
			@RunTime int,
			@avgEntryTemp decimal(18,2),
			@avgExportTemp decimal(18,2),
			@fluxUsed decimal(18,2)

		open Temp_Main
		fetch next from Temp_Main into 

			@MeterID ,
			@StartHeatNum,
			@EndHeatNum ,
			@RunTime,
			@avgEntryTemp ,
			@avgExportTemp ,
			@fluxUsed,
			@StartTime,
			@EndTime

		while @@FETCH_STATUS=0
		begin

			set @Count_Temp=0
			set @Count=DATEDIFF(HOUR,@StartTime,@EndTime)

			while @Count_Temp<@Count
			begin

				insert into db_meterReadingData.dbo.T_MeterUseHeatingDetailInformation
				(
					HRD_ID,
					HRD_MeterNum,
					HDI_StartHeatNum,
					HDI_EndHeatNum,
					HDI_RunTimeInterval,
					HDI_StartTime,
					HDI_EndTime,
					HDI_AvgEntryTemp,
					HDI_AvgExportTemp,
					HDI_FluxUsed,
					HDI_isSettlement
				)
				select 0,@MeterID,@StartHeatNum+convert(decimal(18,2),(@Count_Temp*(@[email protected])/@Count)),convert(decimal(18,2),@StartHeatNum+((@Count_Temp+1)*(@[email protected])/@Count)),0,DATEADD(HOUR,@Count_Temp,@StartTime),DATEADD(HOUR,@Count_Temp+1,@StartTime),@avgEntryTemp,@avgExportTemp,convert(decimal(18,2),@fluxUsed/@Count),1

			set @Count_Temp=	@Count_Temp+1
			end

			fetch next from Temp_Main into 
			@MeterID ,
			@StartHeatNum,
			@EndHeatNum ,
			@RunTime,
			@avgEntryTemp ,
			@avgExportTemp ,
			@fluxUsed,
			@StartTime,
			@EndTime
		end

		close Temp_Main
		deallocate Temp_Main

	end
	end
	set nocount off
go

补充一下在代码中deleted数据表和inserted 数据表,为系统提供的操作虚拟表,下面简单姐晒一下什么情况下待操作税局存储在哪张数据表中。

Insert 操作 inserted 数据表;

delete 操作 delete   数据表;

update 操作 Inserted 数据表和 delerte数据表。

这里还要注意一些细节:

(1)、DELETE 触发器不能捕获 TRUNCATE TABLE 语句。 
        (2)、触发器中不允许以下 Transact-SQL 语句: 
        ALTER DATABASE CREATE DATABASE DISK INIT 
        DISK RESIZE DROP DATABASE LOAD DATABASE 
        LOAD LOG RECONFIGURE RESTORE  DATABASE 
        RESTORE LOG

代码中的触发器正在测试中,测试样本10W希望等达到预期。也希望以上内容能够帮助到你。

Sql server 2008 触发器实现

时间: 2024-11-10 13:12:51

Sql server 2008 触发器实现的相关文章

SQL SERVER 2008向ORACLE 11G迁移示例

来源于:http://www.cnblogs.com/hiizsk/ 由SQL SERVER 2008向ORACLE 11G迁移过程记录之一-表 使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g(一) 使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g(二) 使用Oracle Sql Developer将SQL SERVER 2008数据库移植到Oracle 11g(三) 使用O

笔记-Microsoft SQL Server 2008技术内幕:T-SQL语言基础-08 数据修改

插入数据 T-SQL提供了几种数据插入的语句:INSERT VALUES.INSERT SELECT.INSERT EXEC.SELECT INTO及BULK INSERT. INSERT VALUES语句: INSERT INTO dbo.Orders(orderid, orderdate, empid, custid) VALUES(10001, '20090212', 3, 'A'); SQL Server 2008增强了VALUES语句的功能,允许在一条语句中指定由逗号分隔开的多行记录:

SQL Server 2008的一些新特点及独到之处

SQL Server 2008的一些新特点及独到之处: 设置和安装 SQL Server 2008的设置和安装也有所改进.配置数据和引擎位已经分开了,所以它使创建基本的未配置系统的磁盘图像变得可能了,它使分布到多个服务器变得更容易了.从微软的站点也可以找到安装可用的最新更新.另一个特点是有能力把安装SQL.SP和补丁做一个单一的步骤进行了.另一个的最后的特点是,有能力卸载SP了. 关键的领域 当回顾微软关于SQL Server 2008的文档时注意到的第一条就是术语分类的特点和用途分组的特点.或

SQL Server DDL 触发器(Trigger)-- 创建服务器级别的DDL触发器

SQL Server DDL 触发器(Trigger)-- 创建服务器级别的DDL触发器 若是创建服务器级别的DDL触发器,只要把先前的ON DATABASE改为ON ALL SERVER,即可跟踪服务器级别的事件,使用的原理与数据库级别的DDL触发器相似,区别只在跟踪的事件不同. CREATE TRIGGER ddl_trig_login ON ALL SERVER FOR DDL_LOGIN_EVENTS AS PRINT n'ALTER LOGIN EVENT' SELECT EVENTD

sql server 2008 数据库的完整性约束

一.数据库完整性概述 1.数据库的完整性: ①数据库的完整性是指数据的正确性和相容性 ②数据库完整性是防止不合语义或不正确的数据进入数据库 ③完整性体现了是否真实地反映现实世界 例: 学生的年龄必须是整数,取值范围为14-29: 学生的性别只能是男或女: 学生的学号一定是唯一的: 学生所在的系必须是学校开设的系: 2.DBMS维护数据库完整性的机制: ①提供定义完整性约束条件的机制 DBMS应提供定义数据库完整性约束条件,并把它们存入数据库中. ②提供完整性检查的方法 检查数据是否满足完整性约束

SQL Server 2008数据库视频教程

SQL Server 2008数据库视频教程 SQL Server 一直以来都是大型数据库的代表,一直以来以其查询速度快,性能稳定而闻名.本套教程,由李天生老师亲自授课录制,从最基础的知识讲起,让每一个想学习SQL Server的学员,都可以轻松学会大型数据库管理. 本站最新推出SQL Server 2016视频教程,大家可以看一下http://www.xin3721.com/eschool/sql2016xin3721/ SQL Sever 2008下载地址 第一章 SQL Server基础

SQL Server 2008新特性——更改跟踪

在大型的数据库应用中,经常会遇到部分数据的脱机和多个数据库的合并问题.比如现在有一个全省范围使用的应用程序,每个市都部署了单独的相同的应用程序服务器和数据库服务器,每个月需要将全省所有市的数据全部汇总起来用于出全省的报表,这是一种很常见的数据库合并问题.再比如我们做了一个SmartClient的应用程序,每个客户端都有应用程序和数据库,另外还有一个中心数据库用于汇总所有客户端的数据.每个智能客户端上都可以对自己的数据库进行增删改查,一旦智能客户端连接到网络上时,系统就将客户端数据库中的数据更改全

MSSQL之一 数据库系统简介 与SQL Server 2008概述

前   言 SQL的全称是结构化查询语言(Structured Query Language),它是关系数据库中最常用的语言.SQL不仅可以管理数据库中的数据,而且可以管理关系数据库本身.为了避免各数据库产品之间的SQL语法不兼容,因此由ANSI(American National Standard Institute,美国国家标准局)制定SQL-92标准,目前,大部分DBMS产品都支持该标准. 本课程的目标是使学生掌握结构化查询语言(SQL),具有查询和管理数据库的能力. 本书主要的读者对象

sql server 2008 基础知识

一.配置管理器 1.管理服务 使用配置管理器可以启动.停止.重新启动.继续或暂停服务. 服务器和客户端网络协议 2.SQLSMS 简介:SQLSMS是一个集成环境,用于访问.配置.管理和开发SQL Server的所有组件. 注册服务器:为客户机确定一台SQL Server数据库所在的机器,及服务器. 4.Sqlcmd工具 sqlcmd通过OLE DB与服务器进行通信,使用sqlcmd工具可以在命令提示符窗口中输入T-SQL语句,调用系统过程和脚本文件. T-SQL脚本文件是一个文本文件,可以包含