我被要求对特定数据库中使用的空间进行全面细分。 我知道我可以在SQL Server 2005中使用 sys.dm_db_partition_stats 来计算数据库中每个表的空间大小,但有没有办法确定个人和数据库中存储过程的总大小? (当然,没有打开每一个并计算字符。)
存储过程使用的总空间不太可能很大(与实际的数据相比),但有数百个,它可能会累加。
答案 0 :(得分:12)
;WITH ROUTINES AS (
-- CANNOT use INFORMATION_SCHEMA.ROUTINES because of 4000 character limit
SELECT o.type_desc AS ROUTINE_TYPE
,o.[name] AS ROUTINE_NAME
,m.definition AS ROUTINE_DEFINITION
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o
ON m.object_id = o.object_id
)
SELECT SUM(LEN(ROUTINE_DEFINITION))
FROM ROUTINES
答案 1 :(得分:3)
比计算字符稍微好一点的方法是使用信息schema.routines。您可以将每个例程定义的长度相加为(注意每个例程定义最多为4,000个字符,请参阅下面的没有此限制的方法):
select Sum(Len(Routine_Definition)) from information_schema.routines where routine_type = 'PROCEDURE'
或者你可以返回每个sp的长度
select Len(Routine_Definition), * from information_schema.routines where routine_type = 'PROCEDURE'
存储过程的长度不太可能是问题所在。通常用数据库耗尽空间是因为没有备份日志文件(然后使用dbcc shrinkfile或dbcc shrinkdatabase缩小它)。
在Sql 2000中,这是一个例程,它提供的长度没有上面的4000个字符限制:
DECLARE @Name VarChar(250) DECLARE RoutineCursor CURSOR FOR select Routine_Name from information_schema.routines where routine_type = 'PROCEDURE' DECLARE @Results TABLE ( SpName VarChar(250), SpLength Int ) CREATE TABLE ##SpText ( SpText VarChar(8000) ) OPEN RoutineCursor FETCH NEXT FROM RoutineCursor INTO @Name WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO ##SpText (SpText) EXEC sp_helptext @Name INSERT INTO @Results (SpName, SpLength) (SELECT @Name, Sum(Len(SpText)) FROM ##SpText) TRUNCATE TABLE ##SpText FETCH NEXT FROM RoutineCursor INTO @Name END CLOSE RoutineCursor DEALLOCATE RoutineCursor DROP TABLE ##SpText SELECT SpName, SpLength FROM @Results ORDER BY SpLength DESC SELECT Sum(SpLength) FROM @Results
答案 2 :(得分:2)
Dave_H的解决方案在information_schema.routines表中达到了4,000个字符的限制
试试这个,首先生成一个带有sprocs全文的表,然后对字符长度求和。
--create a temp table to hold the data
create table ##sptext (sptext varchar(1000))
go
--generate the code to insert the full text of your sprocs
select 'insert into ##sptext (sptext) exec sp_helptext '''+specific_name+''';'
from information_schema.routines
where routine_type = 'PROCEDURE'
go
/*Copy the output back to your query analyzer and run it*/
--now sum the results
select sum(len(sptext))
from ##sptext
答案 3 :(得分:2)
需要使用DATALENGTH而不是LEN来获取字节数而不是字符数,因为sys.sql_modules目录视图的定义列是NVARCHAR(MAX),即Unicode
SELECT Type,
SUM(Chars) SizeChars,
SUM(Bytes) SizeBytes,
SUM(Bytes) / 1024. SizeKB,
CAST(SUM(Bytes) / 1024 AS VARCHAR) + '.' + CAST(SUM(Bytes) % 1024 AS VARCHAR) SizeKBRemBytes
FROM
(
SELECT o.type_desc Type,
LEN(sm.definition) Chars,
DATALENGTH(sm.definition) Bytes
FROM sys.sql_modules sm
JOIN sys.objects o ON sm.object_id = o.object_id
) x
GROUP BY Type
ORDER BY Type
答案 4 :(得分:0)
改善Cade Roux答案:
/*
<documentation>
<summary>Count size in bytes veiws, triggers, procedures and function in database.</summary>
<returns>1 data set: RoutinType, SUM LENGTH of objects, SUM DATALENGTH.</returns>
<issues>No</issues>
<author>Cade Roux</author>
<created>2008-10-20</created>
<modified>2019-06-26 by Konstantin Taranov</modified>
<version>1.0</version>
<sourceLink>https://github.com/ktaranov/sqlserver-kit/blob/master/Scripts/Objects_Size_In_Database.sql</sourceLink>
<originalLink>https://stackoverflow.com/a/219740/2298061</originalLink>
</documentation>
*/
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
WITH CTE_Routine AS (
/* Can not use INFORMATION_SCHEMA.ROUTINES because of 4000 character limit */
SELECT o.type_desc AS RoutineType
, o.[name] AS RoutineName
, m.[definition] AS RoutineDefinition
FROM sys.sql_modules AS m
INNER JOIN sys.objects AS o ON m.object_id = o.object_id
)
SELECT RoutineType
, SUM(LEN(RoutineDefinition)) AS RoutineLen
/* DATALENGTH for counting trailing space in the end of objects definitions */
, SUM(DATALENGTH(RoutineDefinition)) / 2 AS RoutineDatalength
FROM CTE_Routine
GROUP BY RoutineType;