Мартин Смит прав, говоря, что sp_MSforeachtable
не удаляет системные таблицы.
Однако, хотя мы можем думать о таких таблицах, как spt_values
и MSreplication_options
, как о системных таблицах, в действительности они являются пользовательскими таблицами в соответствии с 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
Так как же Стейн спасся от переустановки?
Если вы посмотрите, как реализован 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 применяет битовую маску к столбцу category
таблицы sysobjects
, чтобы исключить таблицы, которые не являются mscat
.
Таким образом, таблицы в базе данных master защищены не потому, что они являются системными таблицами, а потому, что они являются таблицами «Microsoft».
Такое использование столбца категории полностью недокументировано в Books Online Все, что у него есть, - это расплывчатое описание:
Используется для публикации, ограничений и идентификации.
Но таблица sysobjects
в любом случае устарела, поэтому ее не следует использовать. :)
Эквивалентный запрос с использованием поддерживаемого представления sys.tables
будет выглядеть так:
SELECT *
FROM sys.tables
WHERE is_ms_shipped = 0;
В моей основной базе данных это также возвращает пустой набор результатов.