SQL Server - 为sysobjects返回SCHEMA

时间:2009-05-27 18:59:03

标签: sql sql-server tsql

如何在sysobjects上进行选择时获得SCHEMA?

我正在修改一个名为 SearchObjectsForText 的存储过程,它只返回Name,但我还想包含SCHEMA。

现在它正在做类似的事情:

SELECT DISTINCT name
FROM sysobjects

我想知道需要加入哪些表来为每个'name'返回SCHEME。

8 个答案:

答案 0 :(得分:55)

如果您的意思是SQL Server 2005或更高版本,请使用sys.objects而不是sysobjects:

SELECT  sys.objects.name, sys.schemas.name AS schema_name
FROM    sys.objects 
INNER JOIN sys.schemas ON sys.objects.schema_id = sys.schemas.schema_id

2005引入了模式。高达2000,用户等于架构。 SQL Server 2000的相同查询:

SELECT  sysusers.name AS OwnerName, sysobjects.name
FROM sysobjects
INNER JOIN sysusers ON sysobjects.uid = sysusers.uid

答案 1 :(得分:14)

在Sql Server 2005(及更高版本)上,您可以使用sys.objects视图:

select 
  name                    as  ObjectName,     
  schema_Name(schema_id)  as  SchemaName
from 
  sys.objects

在Sql Server 2000(及以下版本)中,“schema”具有不同的概念含义。来自MSDN的说明:

在早期版本的SQL Server中,数据库可能包含一个名为“schema”的实体,但该实体实际上是一个数据库用户。 SQL Server 2005是SQL Server的第一个版本,其中架构既是容器又是命名空间。

答案 2 :(得分:4)

您可以改用Information_Schema view(s)吗?

SELECT DISTINCT table_name, table_schema
FROM INFORMATION_SCHEMA.TABLES

根据the MSDN page(适用于SQL Server 2008及更高版本),

  

不要使用INFORMATION_SCHEMA视图来确定对象的架构。查找对象模式的唯一可靠方法是查询sys.objects目录视图。

但是,似乎它们可能指的是一个问题,你有一个表名,并试图找到它的模式,如果有多个具有相同名称的表(在不同的模式中),这将无效。如果您要查询多个结果(而不仅仅是尝试查找特定表的模式),那么它应该没问题。

答案 3 :(得分:3)

我倾向于使用更集中的“sys”视图 - sys.procedures而不是sys.objects。您需要将它与sys.schemas视图一起加入以获取模式名称等。

select
    p.name, 
    s.name 'Schema',
    p.type_desc, p.create_date, p.modify_date
from
    sys.procedures p
inner join
    sys.schemas s ON p.schema_id = s.schema_id

我会开始摆脱使用“sysobjects”,因为微软在联机丛书中明确指出“sysobjects”在将来的版本中会被删除:

此SQL Server 2000系统表作为向后兼容性的视图包含在内。我们建议您使用当前的SQL Server系统视图。若要查找等效的系统视图或视图,请参阅将SQL Server 2000系统表映射到SQL Server 2005系统视图。将在Microsoft SQL Server的未来版本中删除此功能。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。

马克

答案 4 :(得分:1)

只是重复一下这里已经建议的内容,这里是我使用过的,在我的数据库中获取表,存储过程,视图和函数的列表:

SELECT schema_Name(schema_id)  as  SchemaName,
       [name],              --  Name of the Table, Stored Procedure or Function
       [type]               --  'V' for Views, 'U' for Table, 'P' for Stored Procedure, 'FN' for function
FROM sys.objects 
WHERE [type_desc] IN ( 'USER_TABLE', 'SQL_STORED_PROCEDURE', 'VIEW', 'SQL_SCALAR_FUNCTION')
AND [name] NOT LIKE 'sp_%'
AND [name] NOT LIKE 'fn_%'
ORDER BY 3 DESC,        --  type first
        1 ASC,          --  then schema
        2 ASC           --  then function/table name

...而且我们的好朋友 Northwind 会回来......

enter image description here

答案 5 :(得分:0)

在SQL 200中:

select DISTINCT
  name            as  ObjectName,     
  USER_NAME(uid)  as  SchemaName
from 
  sysobjects

在早期版本的SQL Server中,数据库可能包含一个名为“schema”的实体,但该实体实际上是一个数据库用户。

答案 6 :(得分:0)

包含一个选项,用于删除以特定前缀开头的所有对象,也可以选择从某个模式中删除。 顺便说一句,我添加了额外的查询以获取默认情况下未存储在sysobjects上的所有类型。

我已将整个示例脚本上传到GitHub: DropAll_Dnn_Objects.sql

第1部分:临时存储过程:

IF OBJECT_ID('_temp_DropAllDnnObjects') IS NOT NULL
    DROP PROCEDURE _temp_DropAllDnnObjects;
GO

CREATE PROCEDURE _temp_DropAllDnnObjects
    @object_prefix NVARCHAR(30),
    @schema_name sysname = NULL
AS
BEGIN
    DECLARE @sname sysname, @name sysname, @type NVARCHAR(30)
    DECLARE @object_type NVARCHAR(255), @sql NVARCHAR(2000), @count INT = 0

    DECLARE curs CURSOR FOR
        SELECT sname, [name], xtype 
        FROM (
            SELECT SCHEMA_NAME(schema_id) as sname, [name], [type] as xtype
                FROM sys.objects
                WHERE [type] IN ('U', 'P', 'FN', 'IF', 'TF', 'V', 'TR')
                    AND name LIKE @object_prefix + '%'
                    AND (@schema_name IS NULL OR schema_id = SCHEMA_ID(@schema_name))
            UNION ALL
            SELECT SCHEMA_NAME(schema_id) as sname, [name], 'TYPE' as xtype
                FROM sys.types
                WHERE is_user_defined = 1
                    AND [name] LIKE @object_prefix + '%'
                    AND (@schema_name IS NULL OR schema_id = SCHEMA_ID(@schema_name))
            ) a
        ORDER BY CASE xtype
                        WHEN 'P'    THEN 1
                        WHEN 'FN'   THEN 2
                        WHEN 'IF'   THEN 3
                        WHEN 'TF'   THEN 4
                        WHEN 'TR'   THEN 5
                        WHEN 'V'    THEN 6
                        WHEN 'U'    THEN 7
                        WHEN 'TYPE' THEN 8
                        ELSE 9
                    END, name

    OPEN curs;
    FETCH NEXT FROM curs INTO @sname, @name, @type;

    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @count = @count + 1
        -- Configuration point 2
        SET @object_type = CASE @type
                        WHEN 'P'    THEN 'PROCEDURE'
                        WHEN 'FN'   THEN 'FUNCTION'
                        WHEN 'IF'   THEN 'FUNCTION'
                        WHEN 'TF'   THEN 'FUNCTION'
                        WHEN 'TR'   THEN 'TRIGGER'
                        WHEN 'V'    THEN 'VIEW'
                        WHEN 'U'    THEN 'TABLE'
                        WHEN 'TYPE' THEN 'TYPE'
                    END
        SET @sql = REPLACE(REPLACE(REPLACE('DROP <TYPE> [<SCHEMA>].[<NAME>];', 
                        '<TYPE>', @object_type),
                        '<SCHEMA>', @sname),
                        '<NAME>', @name)

        BEGIN TRY  
            PRINT @sql
            EXEC(@sql)
        END TRY  
        BEGIN CATCH  
            PRINT 'ERROR: ' + ERROR_MESSAGE()
        END CATCH  
        FETCH NEXT FROM curs INTO @sname, @name, @type;
    END;

    PRINT CONCAT('Objects Found: ', @Count)
    PRINT ''
    PRINT '------------------------------------------------------'
    PRINT ''

    CLOSE curs;
    DEALLOCATE curs;

    RETURN @Count
END;
GO

它将继续出错(并显示错误消息)。它将返回找到的所有对象的计数。

第2部分:使用参数调用存储过程:

您可以创建一个WHILE循环,以便运行命令,直到没有剩下任何对象(依赖项),如下所示:

DECLARE @count INT = 1
WHILE @count > 0 EXEC @count = _temp_DropAllDnnObjects 'dnn';
SET @count = 1
WHILE @count > 0 EXEC @count = _temp_DropAllDnnObjects 'aspnet';
SET @count = 1
WHILE @count > 0 EXEC @count = _temp_DropAllDnnObjects 'vw_aspnet';
GO

第3部分:最后,摆脱程序:

IF OBJECT_ID('_temp_DropAllDnnObjects') IS NOT NULL
    DROP PROCEDURE _temp_DropAllDnnObjects;
GO

答案 7 :(得分:0)

为什么不使用视图来填充可以使用的临时表呢?

这是我在存储过程中使用的解决方案

这是动态获取模式并将其添加到数据库中不同表中以动态获取其他信息的最佳方法

select @sql ='插入#tables SELECT''[''+ SCHEMA_NAME(schema_id)+''。''+ name +'']''AS SchemaTable from sys.tables'

exec (@sql)

当然#tables是存储过程中的动态表