摘要:今天邹建问我一个问题,系统存储过程中的查询是在用户数据库中执行的,但是用户自己建立的存储过程却是在master中执行的(都是在master中建立的存储过程)。例如:use masterexec sp_helptext 'sp_spaceused'拿到sp_spaceused的代码,把名字改为sp_spaceused2,再执行一次建立这个存储过程。如:use masterGOSET QUOTED_IDENTIFIER ON GOSET ANSI_NULLS OFF GO
create procedure sp_spaceused2 --- 1996/08/20 17:01@objname nvarchar(776) = null, -- The object we want size on.@updateusage varchar(5) = false -- Param. for specifying that -- usage info. should be updated.as……
然后在用户数据库中执行这两个存储过程。一样的代码,但是却得到不一样的结果。USE STSDWGOEXEC sp_spaceusedEXEC sp_spaceused2
database_name database_size unallocated space -------------------------------------------------------------------------------------------------------------------------------- ------------------ ------------------ STSDW 13364.69 MB 7811.36 MB
reserved data index_size unused ------------------ ------------------ ------------------ ------------------ 3896848 KB 3779384 KB 70872 KB 46592 KB
database_name database_size unallocated space -------------------------------------------------------------------------------------------------------------------------------- ------------------ ------------------ STSDW 22.00 MB -3788.58 MB
reserved data index_size unused ------------------ ------------------ ------------------ ------------------ 3896848 KB 3779384 KB 70872 KB 46592 KB
我们会发现其中database_size和unallocated space 的结果不一样,这是什么原因呢,SQL Server 的Bug?
原因是这样的,这是系统存储过程的特有功能,要想达到同样的功能,你除了名字要以sp_开头外(当然也必须是dbo的),还得使用sp_MS_marksystemobject 把你的存储过程标记为MS-shipped。如:sp_MS_marksystemobject 'sp_spaceused2'
sp_MS_marksystemobject 也是一个未公开的存储过程,有兴趣可以自己看看它的代码,代码前一段如下:-- FOR......[
阅读全文]