Подтвердить что ты не робот

SQL Server - возвращает SCHEMA для sysobjects

Как получить SCHEMA при выполнении выбора в sysobjects?

Я модифицирую хранимую процедуру с именем SearchObjectsForText, которая возвращает только имя, но я также хотел бы включить SCHEMA.

Сейчас он делает что-то похожее на это:

SELECT DISTINCT name
FROM sysobjects

Я хотел бы знать, какие таблицы нужно объединить, чтобы вернуть SCHEME для каждого "имени".

4b9b3361

Ответ 1

Если вы имеете в виду 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

Ответ 2

На Sql Server 2005 (и выше) вы можете использовать представление sys.objects:

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

В Sql Server 2000 (и ниже) "схема" имела другое концептуальное значение. Примечание от MSDN:

В предыдущих выпусках SQL Server базы данных могли содержать объект, называемый "схемой", но этот объект был фактически пользователем базы данных. SQL Server 2005 - это первая версия SQL Server, в которой схема представляет собой контейнер и пространство имен.

Ответ 3

Не могли бы вы использовать вид Information_Schema вместо?

SELECT DISTINCT table_name, table_schema
FROM INFORMATION_SCHEMA.TABLES

Согласно странице MSDN (для SQL Server 2008 и выше),

Не используйте представления INFORMATION_SCHEMA для определения схемы объекта. Единственный надежный способ найти схему объекта - запросить представление каталога sys.objects.

Однако похоже, что они, вероятно, относятся к проблеме, в которой у вас есть имя таблицы, и пытаются найти ее схему, которая не будет работать, если бы было несколько таблиц с тем же именем (в разных схемах). Если вы запрашиваете несколько результатов (а не просто пытаетесь найти схему для конкретной таблицы), тогда это должно быть хорошо.

Ответ 4

Я бы предпочел использовать более целенаправленные "sys" views - 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", поскольку Microsoft явно заявляет в Books Online, что "sysobjects" может быть удалена в будущей версии:

Эта системная таблица SQL Server 2000 включена как представление для обратной совместимости. Вместо этого мы рекомендуем использовать текущие системные представления SQL Server. Чтобы найти эквивалентный системный вид или представления, см. "Сопоставление системных таблиц SQL Server 2000 с системными представлениями SQL Server 2005". Эта функция будет удалена в будущей версии Microsoft SQL Server. Избегайте использования этой функции в новых разработках и планируйте изменять приложения, которые в настоящее время используют эту функцию.

Марк

Ответ 5

Чтобы повторить то, что уже было предложено здесь, вот что я использовал, чтобы получить список таблиц, хранимых процедур, представлений и функций в моей базе данных:

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 вернется...

введите описание изображения здесь

Ответ 6

В SQL 200:

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

В предыдущих выпусках SQL Server базы данных могли содержать объект, называемый "схемой", но этот объект был фактически пользователем базы данных.

Ответ 7

Включили возможность удаления всех объектов, начиная с определенного префикса и, необязательно, из определенной схемы. Кстати, я добавил дополнительный запрос для получения всех типов, которые по умолчанию не хранятся в sysobjects.

Я загрузил весь образец script в 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

Ответ 8

Почему бы вместо представления не использовать это для заполнения временной таблицы, которую вы можете использовать?

Это решение, которое я использую в хранимых процедурах

Это лучший способ получить схему динамически и добавить ее в разные таблицы в базе данных, чтобы получить другую информацию динамически

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

exec (@sql)

конечно #tables - это динамическая таблица в хранимой процедуре