實用的儲存過程之一 (轉)
筆者工作的公司採用的是Server,每天都要處理大量的資料,由於筆者進公司的時間比較晚,公司現有的大部分的都是以前的程式設計師留下的,因為他們沒有相關的文件,筆者對於後臺資料庫的很多表的結構和資料都不甚瞭解,給日常的維護造成了很大的麻煩。
在對後臺資料庫進行研究的過程中,我需要得到資料庫的某些相關資訊,比如,我希望知道各個表佔用多少空間,並且排列出來,可以讓我知道哪些表比較大,資料比較多等等——我相信,這可能也是不少資料庫管理員所關心的問題,所以我決心做一個通用的過程。我對的儲存過程sp_spaceused加了一些改動,以適合我的要求。希望這個儲存過程能對大家有些幫助。儲存過程如下:
if exists( name from syss where name='spaceused' and type='p')
Drop procedure spaceused
GO
create procedure spaceused
as
begin
:namespace prefix = o ns = "urn:schemas--com::office" />
declare @id int -- The object id of @objname.
declare @type character(2) -- The object type.
declare @pages int -- Working variable for size calc.
declare @name 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.syiles
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 inde= (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下透過。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10748419/viewspace-1000222/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 從sybase的儲存過程轉向oracle的儲存過程儲存過程Oracle
- JAVA儲存過程(轉)Java儲存過程
- .Net執行SQL/儲存過程之易用輕量工具SQL儲存過程
- MySql儲存過程—2、第一個MySql儲存過程的建立MySql儲存過程
- 使用儲存過程實現分頁列印 (轉)儲存過程
- 幾個實用SQL Server取儲存過程SQLServer儲存過程
- SQL分隔字串的儲存過程 (轉)SQL字串儲存過程
- bbs的資料結構和儲存過程(一) (轉)資料結構儲存過程
- SQL 儲存過程裡呼叫另一個儲存過程SQL儲存過程
- Oracle儲存過程乾貨(一):儲存過程基礎Oracle儲存過程
- 在ORACLE裡用儲存過程定期分割表(轉)Oracle儲存過程
- 用.NET呼叫oracle的儲存過程返回記錄集 (轉)Oracle儲存過程
- SQL Server 儲存過程的運用SQLServer儲存過程
- Linux培訓教程之安全的動態磁碟儲存策略(轉)Linux
- 自動生成對錶進行插入和更新的儲存過程的儲存過程 (轉)儲存過程
- 自動編號的儲存過程 (轉)儲存過程
- 寫了一個MySQL的行轉列的儲存過程薦MySql儲存過程
- 用儲存過程封裝awrrpt指令碼(一)儲存過程封裝指令碼
- 一個儲存過程的問題!儲存過程
- mssql 儲存過程呼叫另一個儲存過程中的結果的方法分享SQL儲存過程
- 用flashback恢復儲存過程儲存過程
- 用PHP呼叫MySQL儲存過程PHPMySql儲存過程
- 用java呼叫oracle儲存過程JavaOracle儲存過程
- 實時監控儲存過程中應用的日誌資訊儲存過程
- 實戰儲存過程排程過程儲存過程
- vertica 如何實現儲存過程?儲存過程
- Mysql 的儲存過程和儲存函式MySql儲存過程儲存函式
- MySQL5儲存過程使用(轉)MySql儲存過程
- mysql儲存過程基本函式(轉)MySql儲存過程函式
- 使用ADO呼叫儲存過程 (轉)儲存過程
- (轉)如何oracle除錯儲存過程Oracle除錯儲存過程
- laravel建立一個儲存過程Laravel儲存過程
- mysql儲存過程一例MySql儲存過程
- 實用單表千萬級分頁儲存過程一(不敢獨享,特此分享)儲存過程
- 用儲存過程動態建立表儲存過程
- 用flashback恢復儲存過程(ZT)儲存過程
- 在儲存過程A中呼叫儲存過程B的結果儲存過程
- MySQL儲存過程詳解 mysql 儲存過程MySql儲存過程