Sql server 2008 意外删除了“主”数据库中的所有数据

Sql server 2008 意外删除了“主”数据库中的所有数据,sql-server-2008,Sql Server 2008,我无意中在“主”数据库而不是临时数据库上使用了此脚本 sp_msforeachtable 'delete from ?' 有没有造成伤害?如果是这样,我如何恢复数据?不,它不应该删除任何内容,假设您在master中没有用户表 测试 exec sys.sp_MSforeachtable 'select ''?''' 不给我任何东西。因此,它似乎排除了系统表,如spt_值 编辑:实际上,从过程的定义来看,它只包括OBJECTPROPERTYo.id,N'IsUserTable'=1的表。Mart

我无意中在“主”数据库而不是临时数据库上使用了此脚本

sp_msforeachtable 'delete from ?'

有没有造成伤害?如果是这样,我如何恢复数据?

不,它不应该删除任何内容,假设您在master中没有用户表

测试

exec sys.sp_MSforeachtable 'select ''?'''
不给我任何东西。因此,它似乎排除了系统表,如spt_值


编辑:实际上,从过程的定义来看,它只包括OBJECTPROPERTYo.id,N'IsUserTable'=1的表。Martin Smith说spmsforeachtable不删除系统表是正确的

然而,尽管我们可能认为spt_值和MSreplication_选项等表是系统表,但根据SQL Server,它们实际上是用户表

在主数据库中运行此查询时:

SELECT name, OBJECTPROPERTY(object_id, N'IsUserTable') AS IsUserTable
FROM master.sys.tables;
我看到以下结果集:

name                  IsUserTable
--------------------- -----------
spt_fallback_db       1
spt_fallback_dev      1
spt_fallback_usg      1
spt_monitor           1
MSreplication_options 1
那么Stijn是如何从重新安装中保存的呢

如果您查看sp_MSforeachtable是如何实现的,您将看到它执行类似于以下操作来选择要删除的表:

declare @mscat nvarchar(12)
select @mscat = ltrim(str(convert(int, 0x0002)))

SELECT *
from dbo.sysobjects o join sys.all_objects syso on o.id = syso.object_id 
where OBJECTPROPERTY(o.id, N'IsUserTable') = 1 and o.category & @mscat = 0;
在我的主数据库中,这将返回一个空的结果集

where子句将位掩码应用于表sysobjects的category列,以排除不是“mscat”的表

因此,主数据库中的表受到保护不是因为它们是系统表,而是因为它们是“Microsoft”表

“类别”列的使用完全没有文档记录,只是一个模糊的描述:

用于发布、约束和标识

但是sysobjects表已被弃用,因此您不应该使用它:

使用受支持的view sys.tables的等效查询如下所示:

SELECT *
FROM sys.tables
WHERE is_ms_shipped = 0;

在我的主数据库中,这也会返回一个空结果集。

还原主数据库的最新备份。你有一个,对吧?我没有。这是一个没有关键数据的个人开发数据库,所以最糟糕的情况是我必须重新安装SQL Server。哇!谢谢我以为我把数据库吹走了,准备重新安装了。如果不检查所需数据库是否已在SQLServerStudio中的下拉菜单中选中,则会发生这种情况。为什么是微软?在打开查询窗口之前,为什么不能让某人明确地选择一个数据库?谢天谢地,他们设置了IsUserTable条件。可用性当然不是微软的标志之一。你的答案是有用的,令人放心的,但OBJECTPROPERTY子句并不是从重新安装中拯救Stijn的原因。在我自己犯了同样的错误之后,我发现了一些关于程序实现的有趣的事情。请看一个例子。