zoukankan      html  css  js  c++  java
  • 实用的存储过程

    笔者工作的公司采用的是SQLServer数据库,每天都要处理大量的数据,由于笔者进公司的时间比较晚,公司现有的大部分的程序都是以前的程序员留下的,因为他们没有相关的文档,笔者对于后台数据库的很多表的结构和数据都不甚了解,给日常的维护造成了很大的麻烦。

    在对后台数据库进行研究的过程中,我需要得到数据库的某些相关信息,比如,我希望知道各个用户表占用多少磁盘空间,并且排列出来,可以让我知道哪些表比较大,数据比较多等等——我相信,这可能也是不少数据库管理员所关心的问题,所以我决心做一个通用的存储过程。我对系统的存储过程sp_spaceused加了一些改动,以适合我的要求。希望这个存储过程能对大家有些帮助。存储过程如下:

    if exists(select name from sysobjects where name='spaceused' and type='p')

    Drop procedure spaceused

    GO

    create procedure spaceused

    as

    begin

     

    declare @id       int                  -- The object id of @objname.

    declare @type       character(2) -- The object type.

    declare       @pages       int                  -- Working variable for size calc.

    declare @dbname sysname

    declare @dbsize dec(15,0)

    declare @logsize dec(15)

    declare @bytesperpage       dec(15,0)

    declare @pagesperMB              dec(15,0)

    declare @objname nvarchar(776)        -- The object we want size on.

    declare @updateusage varchar(5)             -- Param. for specifying that

     

    create table #temp1

    (

           表名              varchar(200) null,

           行数               char(11) null,

           保留空间        varchar(15) null,

           数据使用空间       varchar(15) null,

           索引使用空间       varchar(15) null,

            未用空间          varchar(15) null

    )

    --select @objname='N_dep'                               -- usage info. should be updated.

    select @updateusage='false'

    /*Create temp tables before any DML to ensure dynamic

    ** We need to create a temp table to do the calculation.

    ** reserved: sum(reserved) where indid in (0, 1, 255)

    ** data: sum(dpages) where indid < 2 + sum(used) where indid = 255 (text)

    ** indexp: sum(used) where indid in (0, 1, 255) - data

    ** unused: sum(reserved) - sum(used) where indid in (0, 1, 255)

    */

    declare cur_table cursor for

     select name from sysobjects where type='u'

     

    Open cur_table

    fetch next from cur_table into @objname

     

    While @@FETCH_STATUS=0

    begin

    create table #spt_space

    (

           rows              int null,

           reserved    dec(15) null,

           data        dec(15) null,

           indexp             dec(15) null,

           unused             dec(15) null

    )

     

    /*

    ** Check to see if user wants usages updated.

    */

     

    if @updateusage is not null

           begin

                  select @updateusage=lower(@updateusage)

     

                  if @updateusage not in ('true','false')

                         begin

                                raiserror(15143,-1,-1,@updateusage)

                                return(1)

                         end

           end

    /*

    ** Check to see that the objname is local.

    */

    if @objname IS NOT NULL

    begin

     

           select @dbname = parsename(@objname, 3)

     

           if @dbname is not null and @dbname <> db_name()

                  begin

                         raiserror(15250,-1,-1)

                         return (1)

                  end

     

           if @dbname is null

                  select @dbname = db_name()

     

           /*

           ** Try to find the object.

           */

           select @id = null

           select @id = id, @type = xtype

                  from sysobjects

                         where id = object_id(@objname)

     

           /*

           ** Does the object exist?

           */

           if @id is null

                  begin

                         raiserror(15009,-1,-1,@objname,@dbname)

                         return (1)

                  end

     

     

           if not exists (select * from sysindexes

                                where @id = id and indid < 2)

     

                  if      @type in ('P ','D ','R ','TR','C ','RF') --data stored in sysprocedures

                                begin

                                       raiserror(15234,-1,-1)

                                       return (1)

                                end

                  else if @type = 'V ' -- View => no physical data storage.

                                begin

                                       raiserror(15235,-1,-1)

                                       return (1)

                                end

                  else if @type in ('PK','UQ') -- no physical data storage. --?!?! too many similar messages

                                begin

                                       raiserror(15064,-1,-1)

                                       return (1)

                                end

                  else if @type = 'F ' -- FK => no physical data storage.

                                begin

                                       raiserror(15275,-1,-1)

                                       return (1)

                                end

    end

     

    /*

    ** Update usages if user specified to do so.

    */

     

    if @updateusage = 'true'

           begin

                  if @objname is null

                         dbcc updateusage(0) with no_infomsgs

                  else

                         dbcc updateusage(0,@objname) with no_infomsgs

                  print ' '

           end

     

     

    set nocount on

     

    /*

    ** If @id is null, then we want summary data.

    */

    /*    Space used calculated in the following way

    **       @dbsize = Pages used

    **       @bytesperpage = d.low (where d = master.dbo.spt_values) is

    **    the # of bytes per page when d.type = 'E' and

    **       d.number = 1.

    **    Size = @dbsize * d.low / (1048576 (OR 1 MB))

    */

    if @id is null

    begin

           select @dbsize = sum(convert(dec(15),size))

                  from dbo.sysfiles

                  where (status & 64 = 0)

     

           select @logsize = sum(convert(dec(15),size))

                  from dbo.sysfiles

                  where (status & 64 <> 0)

     

           select @bytesperpage = low

                  from master.dbo.spt_values

                  where number = 1

                         and type = 'E'

           select @pagesperMB = 1048576 / @bytesperpage

     

           select database_name = db_name(),

                  database_size =

                         ltrim(str((@dbsize + @logsize) / @pagesperMB,15,2) + ' MB'),

                  'unallocated space' =

                         ltrim(str((@dbsize -

                                (select sum(convert(dec(15),reserved))

                                       from sysindexes

                                              where indid in (0, 1, 255)

                                )) / @pagesperMB,15,2)+ ' MB')

     

           print ' '

           /*

           ** Now calculate the summary data.

           ** reserved: sum(reserved) where indid in (0, 1, 255)

           */

           insert into #spt_space (reserved)

                  select sum(convert(dec(15),reserved))

                         from sysindexes

                                where indid in (0, 1, 255)

     

           /*

          ** data: sum(dpages) where indid < 2

           **    + sum(used) where indid = 255 (text)

           */

           select @pages = sum(convert(dec(15),dpages))

                         from sysindexes

                                where indid < 2

           select @pages = @pages + isnull(sum(convert(dec(15),used)), 0)

                  from sysindexes

                         where indid = 255

           update #spt_space

                  set data = @pages

     

     

           /* index: sum(used) where indid in (0, 1, 255) - data */

           update #spt_space

                  set indexp = (select sum(convert(dec(15),used))

                                from sysindexes

                                       where indid in (0, 1, 255))

                             - data

     

           /* unused: sum(reserved) - sum(used) where indid in (0, 1, 255) */

           update #spt_space

                  set unused = reserved

                                - (select sum(convert(dec(15),used))

                                       from sysindexes

                                              where indid in (0, 1, 255))

     

           select reserved = ltrim(str(reserved * d.low / 1024.,15,0) +

                                ' ' + 'KB'),

                  data = ltrim(str(data * d.low / 1024.,15,0) +

                                ' ' + 'KB'),

                  index_size = ltrim(str(indexp * d.low / 1024.,15,0) +

                                ' ' + 'KB'),

                  unused = ltrim(str(unused * d.low / 1024.,15,0) +

                                ' ' + 'KB')

                  from #spt_space, master.dbo.spt_values d

                  where d.number = 1

                         and d.type = 'E'

    end

     

    /*

    ** We want a particular object.

    */

    else

    begin

           /*

           ** Now calculate the summary data.

           ** reserved: sum(reserved) where indid in (0, 1, 255)

           */

           insert into #spt_space (reserved)

                  select sum(reserved)

                         from sysindexes

                                where indid in (0, 1, 255)

                                       and id = @id

     

           /*

          ** data: sum(dpages) where indid < 2

           **    + sum(used) where indid = 255 (text)

           */

           select @pages = sum(dpages)

                         from sysindexes

                                where indid < 2

                                       and id = @id

           select @pages = @pages + isnull(sum(used), 0)

                  from sysindexes

                         where indid = 255

                                and id = @id

           update #spt_space

                  set data = @pages

     

     

           /* index: sum(used) where indid in (0, 1, 255) - data */

           update #spt_space

                  set indexp = (select sum(used)

                                from sysindexes

                                       where indid in (0, 1, 255)

                                              and id = @id)

                             - data

     

           /* unused: sum(reserved) - sum(used) where indid in (0, 1, 255) */

           update #spt_space

                  set unused = reserved

                                - (select sum(used)

                                       from sysindexes

                                              where indid in (0, 1, 255)

                                                     and id = @id)

           update #spt_space

                  set rows = i.rows

                         from sysindexes i

                                where i.indid < 2

                                       and i.id = @id

            insert into #temp1

           select name = object_name(@id),

                  rows = convert(char(11), rows),

                  reserved = ltrim(str(reserved * d.low / 1024.,15,0) +

                                ' ' + 'KB'),

                  data = ltrim(str(data * d.low / 1024.,15,0) +

                                ' ' + 'KB'),

                  index_size = ltrim(str(indexp * d.low / 1024.,15,0) +

                                ' ' + 'KB'),

                  unused = ltrim(str(unused * d.low / 1024.,15,0) +

                                ' ' + 'KB')

           from #spt_space, master.dbo.spt_values d

                  where d.number = 1

                         and d.type = 'E'

    Drop table #spt_space

    end

    fetch next from cur_table into @objname

    end

    Close cur_table

    DEALLOCATE cur_table

    Select * from #temp1 order by len(保留空间) desc,保留空间 desc

    Drop table #temp1

    return (0)

    end

    原理很简单,相信大家都能看懂,sp_spaceused几乎原封不动地保留下来,调用也很简单,直接执行即可,没有任何参数,存储过程执行后,将把当前连接的数据库中所有数据表按照从大到小排列出来,还有其他的相关信息。如果能对大家有所参考价值,就请大家能给forgot2000一点掌声鼓励吧,谢谢!

    本存储过程在SQLServer7.0/2000下通过。



    实用的存储过程之二

    笔者工作的公司采用的是SQLServer数据库,每天都要处理大量的数据,由于笔者进公司的时间比较晚,公司现有的大部分的程序都是以前的程序员留下的,因为他们没有相关的文档,笔者对于后台数据库的很多表的结构和数据都不甚了解,给日常的维护造成了很大的麻烦。

    在对后台数据库进行研究的过程中,我需要得到数据库的某些相关信息,比如,公司的数据库中有几个表存放笔者的个人资料,像人事表、工资表、部门表等等,但具体是哪些表,就不是很清楚了,如果要一个一个表地找,可能天亮了也找不完,所以我决定做一个通用的存储过程,能对当前数据库所有字符型字段进行遍历,找出精确匹配含有要查找字符串的表和字段,并且罗列出来。比如,人事表的Name字段,工资表的Salary_Name字段,部门表的Employe_Name字段都有笔者的名字,我希望能把这些找出来。存储过程如下:

    IF EXISTS (SELECT name FROM sysobjects

             WHERE name = 'searchname' AND type = 'P')

       DROP PROCEDURE searchname

    Go

    create procedure searchname @sname varchar(10)

    As

    begin

    create table #TableList(

     tablename char(200),

     colname char(200)

    )

     

    declare @table varchar(200)

    declare @col varchar(200)

     

    set nocount on

    declare curTab scroll cursor for select name from sysobjects where xtype='u'

    open curTab

    fetch next from curTab into @table

    while @@FETCH_STATUS=0

    begin

     declare curCol scroll cursor for select name from syscolumns where (xtype=175 or xtype=167) and (id in (select id from sysobjects where name=@table))

     open curCol

      fetch next from curCol into @col

     while @@FETCH_STATUS=0

     begin

        execute('insert into #TableList select '''+@table+''','''+@col+''' from '+@table+' where '+@col+'='''+@sname+'''')

        fetch next from curCol into @col

     end

     close curCol

     deallocate curCol

     fetch next from curTab into @table

    end

    close curTab

    deallocate curTab

    set nocount off

    select distinct * from #TableList

    drop table #tablelist 

    end

    调用很简单,如想找笔者的名字,调用SearchName ‘forgot2000’即可,查找速度视乎当前数据库的大小而定。希望这个存储过程能对大家有所帮助吧。本人E-mail:coolforgot@sina.com,QQ:33563255,希望能跟大家共同交流,谢谢!

    本存储过程在SQLServer7.0/2000下通过。

  • 相关阅读:
    2015 Multi-University Training Contest 2 1004 Delicious Apples(DP)
    开门人和关门人
    数据降维 实例
    Leetcode题解(5):L58/Length of Last Word
    JavaWeb开发环境搭建
    Linux配置hugepage
    lua的函数初识
    有人离职时经理的反应是?
    svn如何回滚到之前版本
    python用httplib模块发送get和post请求
  • 原文地址:https://www.cnblogs.com/fengye/p/639419.html
Copyright © 2011-2022 走看看