获取数据库下所有的存储过程的定义

本文整理于2012-4

这个问题以前碰到过,方法二是SQL调优培训那天请教了培训老师,培训老师给了我这个思路,我根据老师的思路写出来的,看到遇到技术瓶颈时变通思路是很重要的。

如下:

我们在开发数据库的SP经常会碰到这样的情况,

1.系统上线后由于还有一部分功能不是很完善或是需求变更,需要经常更新存储过程。

有时候会从开发库上更新到一个生产库,或则更新到多个生产库中(各分公司数据库独立)

由于更新的存储过程有些多,而且到后来经常不知道哪些存储过程是 已经修改过的,哪些是新增加的。

这个情况在我原来的公司经常碰到,各分公司各办事处的某些数据库都是独立的,需经常变更SP。

2.由于数据表设计变更或其它变更,需要更新相关的SP,可是不知道哪些SP需要涉及更新,需要获取所有SP的定义后再查找特定字符串。在Avene工作中有碰到这种情况。

有以下2个方法获取所有SP定义:

方法一

declare @proc_text varchar(max)

DECLARE get_proc_text_cursor CURSOR FOR

SELECT 'if object_id(N'''+ [name] +''') is not null drop proc ' + [name] + CHAR(10) + CHAR(13) + ' GO ' + CHAR(10) + CHAR(13) + definition + CHAR(10) + CHAR(13) +' GO'

FROM sys.sql_modules

inner join sysobjects on sys.sql_modules.object_id = sysobjects.id and type='p'

OPEN get_proc_text_cursor

FETCH NEXT FROM get_proc_text_cursor

INTO @proc_text

WHILE @@FETCH_STATUS = 0

BEGIN

print @proc_text

FETCH NEXT FROM get_proc_text_cursor

INTO @proc_text

END

CLOSE get_proc_text_cursor

DEALLOCATE get_proc_text_cursor

这个方法的优点是快捷方便,可是当SP定义大于8000个字节时,会阶段SP的定义,不能完整获取超长的SP的定义。在我们Avene的数据库中有的SP定义已超过了2000行了。

方法2

在方法1的基础上加以改进折中

use avene_dev

go

--一数据准备

CREATE TABLE sp_def--这个表存储SP的定义,表命名尽量短小,因为要拼接字符串时候要用到

(

id INT IDENTITY(1,1),

definiton VARCHAR(max)

)

create table tableobject--这个表存储SP的命名

(

objectname varchar(1000),

)

go

CREATE TRIGGER tr ON tableobject--将SP命名插入该表时触发器生成组合字符串

AFTER INSERT

AS

DECLARE @sql VARCHAR(max)

SET @sql=''

SELECT @sql=@sql+'insert sp_def EXEC sp_helptext ''' + objectname+ '''; '

FROM Inserted;

SELECT @sql '组合完成的字符串'

---------

--二数据执行

--1拼接语句

TRUNCATE TABLE tableobject

INSERT tableobject SELECT OBJECT_SCHEMA_NAME(id)+'.'+name from sys.sysobjects where xtype='p'

--得到类似如下的语句,注意该语句不能超过个字节,SQLserver本身的限制

--insert into EXEC sp_helptext 'dbo.Possp_smsByCity'; insert into EXEC sp_helptext 'dbo.';

--2执行上句生成的字符串

TRUNCATE TABLE sp_def

--执行'拼接字符串'

--3利用游标输出sp_def表中的SP的定义

go

declare @proc_text varchar(max)

DECLARE get_proc_text_cursor CURSOR FOR

SELECT definiton

FROM sp_def ORDER BY id

OPEN get_proc_text_cursor

FETCH NEXT FROM get_proc_text_cursor

INTO @proc_text

WHILE @@FETCH_STATUS = 0

BEGIN

print @proc_text

FETCH NEXT FROM get_proc_text_cursor

INTO @proc_text

END

CLOSE get_proc_text_cursor

DEALLOCATE get_proc_text_cursor

总结:方法2只是在方法1上做了折中变通,还没有突破字符串变量长度为8000个字节的限制,不知道Sqlserver是否有支持超过8000个字节的文本变量。

本人只是抛砖引玉,如果哪位有更好的方法实现或者能突破文本变量为8000个字节的,望不吝赐教!

原文地址:https://www.cnblogs.com/dotagg/p/6372089.html