如何检查SQL Server表是否为系统表

时间:2012-04-05 13:55:36

标签: sql-server tsql ssms

使用存储过程sp_msforeachtable,可以为数据库中的所有表执行脚本。

但是,有一些系统表我想从中排除。本能地,我会检查属性IsSystemTableIsMSShipped。这些不能像我期望的那样工作 - 我有一个名为__RefactorLog的表:

System table

但是当我查询这是一个系统还是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如何检查表是否是系统对象?

4 个答案:

答案 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]

(其中tblsys.tables)的别名

所以它似乎是一个组合 - 来自is_ms_shipped的{​​{1}}为1,或者具有特定的扩展属性集。

答案 1 :(得分:2)

与SSMS建议相比,

__ 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 '