惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News - Newest:
Hacker News - Newest: "LLM"
S
SegmentFault 最新的问题
The Cloudflare Blog
T
The Exploit Database - CXSecurity.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy & Cybersecurity Law Blog
有赞技术团队
有赞技术团队
www.infosecurity-magazine.com
www.infosecurity-magazine.com
雷峰网
雷峰网
Google DeepMind News
Google DeepMind News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
The Hacker News
The Hacker News
人人都是产品经理
人人都是产品经理
阮一峰的网络日志
阮一峰的网络日志
大猫的无限游戏
大猫的无限游戏
L
Lohrmann on Cybersecurity
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
博客园 - 叶小钗
量子位
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
S
Secure Thoughts
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
Help Net Security
Help Net Security
爱范儿
爱范儿
C
Cybersecurity and Infrastructure Security Agency CISA
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
腾讯CDC
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
C
Check Point Blog
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
T
Tor Project blog
NISL@THU
NISL@THU
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
InfoQ
The Register - Security
The Register - Security
Recent Announcements
Recent Announcements
N
News and Events Feed by Topic
B
Blog RSS Feed

博客园 - Carlwave-陆飞(Fei.Lu)

找到一个在上海租房非常不错的网站 - 一步租房网,推荐推荐,综合了赶集,58同城,搜房,安居客等所有的信息 SQL SERVER2012中使用游标来备份数据库 阔别N年,仅仅记录一下,独自一人饮酒,这滋味。。。你懂的。。 推荐一处买望远镜的网站:博士能望远镜上海官方销售 - 38度光 http://www.38optics.com VS.net图片加水印的代码 悼哀三天,沉痛追忆一个故人的“离别” 选择斯诺克球杆的基本要素 斯诺克之星 - 白沙台球杆 官方 及 派蔻台球杆 官方 www.snkstar.com - 最专业的台球杆销售网站 自制控件:点击页面上的按纽,弹出一个正在处理的层,处理完毕后该层消失 我最近在忙啥列?好好回忆下。。。 使用radion button选择datagrid的行(在datagrid中使用radio buttons) 在伦敦生活工作-2(由于本人懒惰的关系,这篇估计是最后一篇了,呵呵) 在伦敦工作生活—随笔-1 第一次醉酒呕吐,纪念一下~~~ 转:《35岁前成功的12条黄金法则》,在新的一年激励下所有辛苦的程序员 ASP.NET 页面对象模型 电信要再这麽任意搞垄断,任意妄为,等中国的网民都成了网络暴民看他怎么收场!! VS2005+SQL2005 Reporting动态增加报表(*.rdlc)数据源 SQL 2005 Reporting Services:物理分页和逻辑分页
自动记录数据库存储过程的更新和改变,并产生日志
Carlwave-陆飞(Fei.Lu) · 2007-11-19 · via 博客园 - Carlwave-陆飞(Fei.Lu)
 

一、        简介

使用环境:SQL Server

    在项目开发过程中,项目管理者通常都很希望对项目的开发进展有一个日志的记录。代码的记录和管理可以通过TFS或者VSS等工具去管理。但是数据库却没有记录开发日志这一功能。这在实际开发中很不方便,特别是大量的存储过程改动。

       那么针对这一个需求,在数据库中定时执行一个Job,让其自动记录存储过程的改动,以完成对数据库存储过程改动的一个记录。

二、        实际效果

Sp_id

change_date

action_type

sp_name

755585830

2007-11-13

Added

Sp_a

451584747

2007-11-13

Update

Sp_b

2119014630

2007-11-13

Update

Sp_c

2119014630

2007-11-13

Update

Sp_d

771585887

2007-11-13

Deleted

Sp_e

三、        实现原理

由于数据库中所有的存储过程代码都记录在系统表Sys_comments中,所以我们可以通过比较不同时间点代码的方式去实现记录一定时间范围内的存储过程变化。

比如:在今天早上0100我们把所有存储过程代码从系统表中取出,并记录。然后到明天早上再重复这一过程,将两次取出的不同结果进行比较,取出有变化的存储过程并记录,认为这些存储过程在这一时间范围内存在更新。

四、        实现代码

其实原理很简单,就是一个循环比较的方式,所以也不需要大费周章的去介绍了,那么下面就把实现相关的代码和流程贴出来。

1建立数据表

在数据库建立三张表,sps_old, sps_new, sps_log

Sps_old:记录前一次系统中所有存储过程代码,以备比较

Sps_new:当前所有存储过程的代码,与sps_log_old中的数据比较

Sps_log:记录在两个时间点范围内变化的存储过程名字和变化时间

表结构:

/****** Sps_log ******/

CREATE TABLE [dbo].[sps_log](

       [sp_id] [int] NULL,

       [change_date] [datetime] NULL,

       [action_type] [char](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

       [sp_name] [varchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NULL

) ON [PRIMARY]

/****** Sps_new ******/----------------------------------------------------------------

CREATE TABLE [dbo].[sps_new](

       [sp_id] [int] NULL,

       [colid] [smallint] NULL,

       [sp_name] [varchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

       [sp_content] [varchar](4000) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

       [record_date] [datetime] NULL

) ON [PRIMARY]

/******Sps_old******/-----------------------------------------------------------------------------------

CREATE TABLE [dbo].[sps_old](

       [sp_id] [int] NULL,

       [colid] [smallint] NULL,

       [sp_name] [varchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

       [sp_content] [varchar](4000) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,

       [record_date] [datetime] NULL

) ON [PRIMARY]

----------------------------------------------------------------------------------------------------------------

2建立进行比较用的存储过程,并记录结果集

/*------------------------------------------------------------------------------------------------------

 -- Function   :      sps_log_add

 -- Description       :      record all sps change log

 --1 get all new sps (find sps which in new table not in old table)

 --2 get all deleted sps (find sps which in old table not in new table)

 --3 get all updated sps (find sps which in old talbe are not same in new table)

 -- any change will record into sps_log table

------------------------------------------------------------------------------------------------------*/

CREATE procedure [dbo].[sps_log_add]

as

-- clear out sps_new

truncate table sps_new

-- fill into sps_new

insert into       sps_new

(sp_id,colid,sp_name,sp_content,record_date)

select

       a.id,

       a.colid,

       b.name,

       a.[text],

       getdate()

from

       syscomments a

left join

       sysobjects b

 on a.id = b.id

where b.type='P' and b.name not like 'dt_%'

-- Find new sp

insert into

       sps_log

select distinct

       sp_id,

       getdate(),

       'Added',

       sp_name

from

       sps_new

where

       sp_id not in (select distinct sp_id from sps_old)

-- Find deleted sp

insert into

       sps_log

select distinct

       sp_id,

       getdate(),

       'Removed',

       sp_name

from

       sps_old

where

       sp_id not in (select distinct sp_id from sps_new)

-- compare existing sp

DECLARE @ProcID int

declare @count_new int

declare @count_old int

declare @text_new varchar(4000)

declare @text_old varchar(4000)

declare @name varchar(150)

declare @i int

DECLARE SearchProc CURSOR FOR

select distinct

       sp_id

from

       sps_new

where

       sp_id in (select distinct sp_id from sps_old)

order by

       sp_id

open SearchProc

FETCH NEXT FROM SearchProc

INTO @ProcID

WHILE @@FETCH_STATUS >=0

BEGIN

       -- colid quantity

       select @count_new=count(colid) from sps_new where sp_id = @ProcID

      select @count_old=count(colid) from sps_old where sp_id = @ProcID

-- if count of colid is unequal, sp was updated.

       if @count_new <> @count_old

              begin

                     -- Record change

                     insert into       sps_log(sp_id,change_date,action_type) values(@ProcID,getdate(),'Update')

              end

       else -- @count_new = @count_old, if count of colid is equal

              begin

                     set @i=1 -- Reset Counter

                     while @i<=@count_new -- colid

                     begin

                                   -- sp content

select @text_new = sp_content from sps_new

where sp_id = @ProcID and colid = @i

                                   select @text_old = sp_content from sps_old

where sp_id = @ProcID and colid = @i

-- if content is different, sp was updated.

                                   if @text_new <> @text_old        

                                          begin      

                                                 -- Record change

                                                 select @name = [name] from sysobjects where id=@ProcID

                                                 insert into sps_log(sp_id,change_date,action_type,sp_name)

values(@ProcID,getdate(),'Update',@name)

                                          end

                                   set @i= @i+1 -- Counter + 1

                     end

              end

       FETCH NEXT FROM SearchProc

    INTO @ProcID

END

CLOSE SearchProc

DEALLOCATE SearchProc

-- clear out sps_new

truncate table sps_old

-- fill into sps_old with sps_new

insert into sps_old select * from sps_new

----------------------------------------------------------------------------------------------------------------------

3创建一个存储过程从sps_log中获取指定时间内的数据

/*

 -- Function   : sps_log_get

 -- Description       : Show sps change in a period of time

*/

CREATE PROCEDURE [dbo].[sps_log_get]

@from_date datetime,

@to_date datetime

as

       select

              sp_name,

              action_type,

              CONVERT(varchar(10),change_date,102) as change_date

       from

              sps_log

       where

              change_date between @from_date and @to_date

       group by

              sp_name,action_type,CONVERT(varchar(10),change_date,102)

       order by

              CONVERT(varchar(10),change_date,102) asc

五、        实际应用和配置

在数据库中新建一个Job,代码为exec sps_log_add,一般运行可以设置为每天的零晨,一天一次比较合理,这样便能把每天做的改动记录下来。

六、        查看日志

直接运行存储过程exec sps_log_get ‘2007-11-01’,’2007-11-30’。便能查看所有在这一段时间内的存储过程变化。

    如果您有更好的办法,还请务必留言。谢谢!