SQL Server - Return SCHEMA for sysobjects

后端 未结 8 1429
旧巷少年郎
旧巷少年郎 2020-12-29 21:30

How to I get the SCHEMA when doing a select on sysobjects?

I am modifing a stored procedure called SearchObjectsForText which returns only the Name

相关标签:
8条回答
  • 2020-12-29 22:10

    In SQL 200:

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

    In earlier releases of SQL Server, databases could contain an entity called a "schema", but that entity was effectively a database user.

    0 讨论(0)
  • 2020-12-29 22:12

    I would favor using the more focused "sys" views - sys.procedures instead of sys.objects. You'll need to join it with the sys.schemas view to get schema name and such.

    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
    

    I would start to get away from using "sysobjects" since Microsoft clearly states in Books Online that "sysobjects" is subject to removal in a future release:

    This SQL Server 2000 system table is included as a view for backward compatibility. We recommend that you use the current SQL Server system views instead. To find the equivalent system view or views, see Mapping SQL Server 2000 System Tables to SQL Server 2005 System Views. This feature will be removed in a future version of Microsoft SQL Server. Avoid using this feature in new development work, and plan to modify applications that currently use this feature.

    Marc

    0 讨论(0)
  • 2020-12-29 22:14

    If you mean SQL Server 2005 or higher, use sys.objects instead of 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 introduced schemas. up to 2000, users equaled schemas. The same query for SQL Server 2000:

    SELECT  sysusers.name AS OwnerName, sysobjects.name
    FROM sysobjects
    INNER JOIN sysusers ON sysobjects.uid = sysusers.uid
    
    0 讨论(0)
  • 2020-12-29 22:18

    Instead of a view, why not use this to populate a temporary table you can use?

    This is the solution I use in stored procedures

    This is the best way to get a schema dynamically and add it to the different tables within a database in order to get other information dynamically

    select @sql = 'insert #tables SELECT ''[''+SCHEMA_NAME(schema_id)+''.''+name+'']'' AS SchemaTable FROM sys.tables'

    exec (@sql)
    

    of course #tables is a dynamic table in the stored procedure

    0 讨论(0)
  • 2020-12-29 22:21

    Could you use the Information_Schema view(s) instead?

    SELECT DISTINCT table_name, table_schema
    FROM INFORMATION_SCHEMA.TABLES
    

    According to the MSDN page (for SQL Server 2008 and above),

    Do not use INFORMATION_SCHEMA views to determine the schema of an object. The only reliable way to find the schema of a object is to query the sys.objects catalog view.

    However, it seems that they're probably referring to an issue where you have a table name and are trying to find its schema, which wouldn't work if there were multiple tables with the same name (in different schemas). If you're querying for multiple results (not just trying to find the schema for a specific table), then it should be fine.

    0 讨论(0)
  • 2020-12-29 22:24

    Have included an option to delete all objects starting with certain prefix and optionally from certain schema. By the way, I added extra query to get all types which are not stored on sysobjects by default.

    I have uploaded entire sample script to GitHub: DropAll_Dnn_Objects.sql

    Part 1: Temporary Stored Procedure:

    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
    

    It will continue on errors (and display the error message). It will return a count of all objects found.

    Part 2: Call Stored Procedure with parameters:

    You can create a WHILE loop in order to run the command until no object is left (dependencies), as follows:

    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
    

    Part 3: Finally, get rid of the procedure:

    IF OBJECT_ID('_temp_DropAllDnnObjects') IS NOT NULL
        DROP PROCEDURE _temp_DropAllDnnObjects;
    GO
    
    0 讨论(0)
提交回复
热议问题