使用存储过程sp_msforeachtable
,可以为数据库中的所有表执行脚本。
但是,有一些系统表我想从中排除。本能地,我会检查属性IsSystemTable
或IsMSShipped
。这些不能像我期望的那样工作 - 我有一个名为__RefactorLog
的表:
但是当我查询这是一个系统还是MS Shipped表时,SQL Server报告我的表都不是系统表:
exec (N'EXEC Database..sp_msforeachtable "PRINT ''? = '' + CAST(ObjectProperty(Object_ID(''?''), ''IsSystemTable'') AS VARCHAR(MAX))"') AS LOGIN = 'MyETLUser'
-- Results of IsSystemTable:
[dbo].[__RefactorLog] = 0
[schema].[myUserTable] = 0
和
exec (N'EXEC Database..sp_msforeachtable "PRINT ''? = '' + CAST(ObjectProperty(Object_ID(''?''), ''IsMSShipped'') AS VARCHAR(MAX))"') AS LOGIN = 'MyETLUser'
-- Results of IsMSShipped:
[dbo].[__RefactorLog] = 0
[schema].[myUserTable] = 0
当我查看表的属性(在SSMS内)时,该表被标记为系统对象。虽然(AFAIK)不存在像IsSystemObject
这样的对象属性。
除了object属性外,如何检查表是否是系统对象? SSMS如何检查表是否是系统对象?
答案 0 :(得分:9)
在对象资源管理器中打开“系统表”文件夹时,管理工作室2008似乎运行了一些非常难看的代码,关键位似乎是:
CAST(
case
when tbl.is_ms_shipped = 1 then 1
when (
select
major_id
from
sys.extended_properties
where
major_id = tbl.object_id and
minor_id = 0 and
class = 1 and
name = N''microsoft_database_tools_support'')
is not null then 1
else 0
end
AS bit) AS [IsSystemObject]
(其中tbl
是sys.tables
)的别名
所以它似乎是一个组合 - 来自is_ms_shipped
的{{1}}为1,或者具有特定的扩展属性集。
答案 1 :(得分:2)
__ refactorlog是一个用户表。在部署期间使用它来跟踪无法从当前数据库状态推断出的架构更改,例如重命名表。
如果所有其他用户表都在自定义(非dbo)架构中,则可以结合使用isMSshipped / isSystemTable属性和架构名称来确定某个表是否在您的脚本的“范围内”。 / p>
答案 2 :(得分:1)
过去我曾假设在sys.objects表中,列is_ms_shipped指示对象是否是系统对象。 (此列由其他系统表继承,例如sys.tables。)
此标志可以通过过程sp_ms_markSystemObject设置。然而,这是一个没有文档记录的程序,微软不支持,我认为我们不应该知道它,所以我没有告诉你它。
答案 3 :(得分:0)
我错过了什么吗?
但是,有一些系统表我想从那个
中排除
至少在SQL Server 2008上,sp_MSforeachtable
已经排除系统表,因为它的摘录显示:
+ N' where OBJECTPROPERTY(o.id, N''IsUserTable'') = 1 ' + N' and o.category & ' + @mscat + N' = 0 '