在没有权限运行 Exec sp_updatestats 时,用这个存储过程来更新数据库中所有表的统计信息


GO
/****** Object:  StoredProcedure [dbo].[mysp_updatestats]    Script Date: 2023/6/7 15:02:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

-- 在没有权限运行 Exec sp_updatestats 时,用这个存储过程来更新数据库中所有表的统计信息
-- 当前采用的是 UPDATE STATISTICS [dbo].[mytablename]  WITH FULLSCAN 的方式
-- 作者:huang wanjing
-- 执行方式: exec [mysp_updatestats]
create procedure [dbo].[mysp_updatestats]

as

	-- required so it can update stats on ICC/IVs
	set ansi_warnings on
	set ansi_padding on
	set arithabort on
	set concat_null_yields_null on
	set numeric_roundabort off

	declare @exec_stmt_head nvarchar(4000)	-- "UPDATE STATISTICS [sysname].[sysname] "

	declare @updated_count int
	declare @skipped_count int

	declare @sch_id int
	declare @schema_name sysname
	declare @table_name sysname
	declare @table_id int
	declare @table_type char(2)
	declare @schema_table_name nvarchar(640) -- assuming sysname is 128 chars, 5x that, so it's > 128*4+4

	--declare @compatlvl tinyint

	declare 
<think>好的,用户现在遇到了在SQL Server中执行EXEC sp_spaceused 'a'提示对象'a'在master数据库中不存在的问题。我需要帮他解决这个问题。首先,我应该回想一下之前用户的提问和我的回答。用户之前询问的是如何查询a的空间占用情况,我提供了两种方法,其中推荐使用sp_spaceused存储过程。但现在用户在使用这个方法遇到了错误,说对象在master数据库不存在。 首先,我需要分析可能的原因。用户可能当前连接的数据库是master,而a并不在master中,而是在另一个数据库中。这候执行sp_spaceused 'a'自然找不到,因为系统会在当前数据库下查找对象。所以解决办法应该是让用户确认当前数据库上下文,并切换到正确的数据库后再执行命令。 另外,用户可能在执行存储过程没有正确指定数据库名称作为架构前缀,比如如果a在dbo架构下,可能需要用'dbo.a'来引用。不过,如果用户已经在正确的数据库上下文中,可能不需要架构前缀。但有候如果属于不同的架构,比如不是dbo,那么必须加上架构名,否则会找不到对象。 还有一种可能是用户输入的名有误,或者存在大小写问题,但SQL Server默认是不区分大小写的,所以这可能不是主要原因。不过,如果数据库设置了区分大小写的排序规则,那么名的大小写就必须完全匹配。这候用户需要检查名是否正确。 接下来,我应该给出具体的解决步骤。首先,让用户检查当前数据库是否是目标数据库。可以通过执行SELECT DB_NAME()来确认当前数据库。如果不是,就使用USE语句切换到正确的数据库。然后再次执行EXEC sp_spaceused 'a'。 如果切换数据库后仍然报错,可能需要检查名是否正确,是否存在拼写错误,或者是否属于特定的架构。例如,如果属于schema1,那么应该使用EXEC sp_spaceused 'schema1.a'。 此外,用户可能需要更新统计信息,或者检查是否有权限问题。但根据错误提示,更可能的是数据库上下文的问题。 然后,我需要考虑用户可能的其他疑问,比如如何永久设置默认数据库,避免每次连接都要切换。这候可以建议用户在登录指定默认数据库,或者在SSMS中设置连接的默认数据库属性。 最后,总结解决方案,分步骤说明,并给出示例代码,帮助用户一步步操作。同,提醒用户注意名和架构的正确性,以及数据库上下文的重要性。这样用户应该能够解决对象不存在的问题了。</think>在 SQL Server 中执行 `EXEC sp_spaceused 'a'` 提示 **“对象'a'在数据库'master'中不存在”**,根本原因是当前会话的数据库上下文(context)被默认设置为 `master` 数据库,而非目标所在的数据库。以下是具体解决方案: --- ### 原因分析 1. **默认数据库上下文**:用户登录默认连接到 `master` 数据库,而 `a` 实际存储在另一个用户数据库(如 `YourDB`)中。 2. **对象路径未指定**:未显式限定数据库名称或架构名称。 --- ### 解决方案 #### 方法一:切换当前数据库上下文 通过 `USE` 语句明确切换到目标数据库: ```sql -- 切换至目标数据库(例如 YourDB) USE YourDB; GO -- 再次执行存储过程 EXEC sp_spaceused 'a'; ``` #### 方法二:使用完全限定名称(推荐) 通过 `[数据库名].[架构名].[名]` 格式直接指定路径: ```sql -- 指定目标数据库和架构(例如 dbo 架构) EXEC YourDB.dbo.sp_spaceused 'YourDB.dbo.a'; ``` #### 方法三:验证名与架构 - **检查是否存在**: ```sql -- 列出当前数据库中所有用户 SELECT name FROM sys.tables WHERE name = 'a'; ``` - **验证架构归属**: ```sql -- 查看所属的架构 SELECT SCHEMA_NAME(schema_id) AS SchemaName, name FROM sys.tables WHERE name = 'a'; ``` #### 方法四:检查用户默认数据库 若频繁出现此问题,需调整登录用户的默认数据库: ```sql -- 修改登录用户的默认数据库(例如 YourDB) ALTER LOGIN [YourLoginName] WITH DEFAULT_DATABASE = YourDB; ``` --- ### 关键验证步骤 1. **确认当前数据库**: ```sql SELECT DB_NAME() AS CurrentDatabase; -- 输出当前连接数据库 ``` ![示例输出](https://example.com/db_context.png) *若结果为 `master`,则需切换数据库*[^1]。 2. **权限检查**: - 确保用户对目标数据库有 `VIEW DATABASE STATE` 权限[^2]。 - 若使用 Azure SQL Database,需检查防火墙规则和访问策略[^3]。 --- ### 示例场景 假设 `a` 实际位于数据库 `SalesDB` 的 `dbo` 架构下: ```sql -- 错误:当前数据库为 master EXEC sp_spaceused 'a'; -- 报错对象不存在 -- 正确:显式指定数据库 EXEC SalesDB.dbo.sp_spaceused 'a'; -- 或先切换数据库 USE SalesDB; EXEC sp_spaceused 'a'; ``` --- ### 扩展排查 如果仍报错,需进一步检查: 1. **名大小写敏感性**:若数据库配置了区分大小写的排序规则,需严格匹配大小写。 2. **临或系统**:`sp_spaceused` 不支持查询临(如 `#temp`)或系统。 --- ### 相关问题 1. 如何批量查询 SQL Server 中所有的空间占用? 2. 为什么 `sp_spaceused` 返回的索引空间与手动计算不一致? 3. 如何修复 SQL Server 中“对象不存在”的权限问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值