2009-05-27 4 views
26

Jak uzyskać SCHEMA podczas wybierania obiektów sysobject?Serwer SQL - Powrót SCHEMA dla sysobjects

Modyfikuję procedurę przechowywaną o nazwie SearchObjectsForText, która zwraca tylko nazwę, ale chciałbym również uwzględnić SCHEMA.

Teraz robi coś podobnego do tego:

SELECT DISTINCT name 
FROM sysobjects 

Chciałbym wiedzieć, co tabele muszą być połączone, aby powrócić do systemu dla każdego „imię”.

Odpowiedz

53

Jeśli masz na myśli SQL Server 2005 lub nowszy, należy sys.objects zamiast 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 wprowadzono schematów. do 2000 roku użytkownicy równały się schematom. To samo zapytanie do SQL Server 2000:

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

Ze względu na układ procedury przechowywanej SearchObjectsForText, skończyłem używając tej metody. Ale podobała mi się też "nauka drutu", ponieważ była znacznie prostsza. –

+0

Warto zauważyć, że to * nie * da takie same wyniki. Na przykład sysobjects zwróci widoki katalogu systemowego, podczas gdy sys.objects nie ma wartości –

4

można użyć Information_Schema view(s) zamiast?

SELECT DISTINCT table_name, table_schema 
FROM INFORMATION_SCHEMA.TABLES 

Według the MSDN page (dla SQL Server 2008 i powyżej),

Nie używaj widoki INFORMATION_SCHEMA do określenia schematu obiektu. Jedynym niezawodnym sposobem znalezienia schematu obiektu jest zapytanie do widoku katalogu sys.objects.

Wydaje się jednak, że są one prawdopodobnie odnosząc się do kwestii, gdzie masz nazwy tabeli i próbują znaleźć swój schemat, który nie będzie działać, jeśli nie było wiele tabel o tej samej nazwie (w różny schematy). Jeśli pytasz o wiele wyników (nie tylko próbujesz znaleźć schemat dla konkretnej tabeli), to powinno być dobrze.

+0

Chciałbym móc, ale nie chcę zbytnio zmieniać istniejącej procedury przechowywanej i po prostu robienie łączenia byłoby łatwiejsze. Dzięki za sugestię. Dałem ci do tego prawo głosu. :) –

+6

Nie używasz widoków INFORMATION_SCHEMA do ustalenia schematu obiektu? Przysięgam! Dla mnie brzmi to jak błąd, który należy naprawić, a nie jak funkcja udokumentowana w MSDN. Jeśli się zgodzisz, prześlij opinię na temat witryny MSDN. –

+1

@Alex Jestem absolutnie pewien, że "określenie schematu obiektu" oznacza, biorąc pod uwagę nazwę tabeli (lub identyfikator obiektu), ustalenie, jaki jest jej schemat. I tak, nie można tego zrobić z widokami INFORMATION_SCHEMA, ponieważ widoki informacji_schematu nie ujawniają identyfikatora obiektu, a więc znając tylko nazwę tabeli, może być wiele tabel o tej nazwie pod wieloma schematami. Po prostu wyliczając listę obiektów wraz z ich schematami i nazwami, całkowicie bezpieczne jest korzystanie z widoków INFORMATION_SCHEMA. Zauważ, że możesz również użyć funkcji systemowych na identyfikatorach obiektów, aby zwrócić również nazwy schematów. – ErikE

14

na SQL Server 2005 (i powyżej) można użyć sys.objects zobaczyć:

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

w SQL Server 2000 (i poniżej), "schemat" miał inny koncepcyjne znaczenie. Uwaga od MSDN:

We wcześniejszych wydaniach programu SQL Server bazy danych mogły zawierać encję nazywaną "schematem", ale ta jednostka była faktycznie użytkownikiem bazy danych. SQL Server 2005 to pierwsza wersja programu SQL Server, w której schemat jest zarówno kontenerem, jak i przestrzenią nazw.

3

Wolałbym używać bardziej skupionych widoków "sys" - sys.procedures zamiast sys.objects. Musisz dołączyć do niego w widoku sys.schemas, aby uzyskać nazwę schematu i inne.

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 

chciałbym zacząć, aby uciec z pomocą „sysobjects”, ponieważ Microsoft wyraźnie stwierdza w Books Online, że „sysobjects” podlega usunięciu w przyszłych wersjach:

to SQL Server 2000 tabela systemowa jest włączone jako widok dla zgodności wstecznej. Zalecamy zamiast tego używać bieżących widoków systemowych SQL Server. Aby znaleźć równoważny widok systemu lub widoki, zobacz Mapowanie tabel systemowych SQL Server 2000 na widoki systemu SQL Server 2005. Ta funkcja zostanie usunięta w przyszłej wersji programu Microsoft SQL Server.Unikaj korzystania z tej funkcji w nowych pracach programistycznych i planuj modyfikowanie aplikacji, które obecnie używają tej funkcji.

Marc

+0

Dzięki za pomysł. Jest to dość duża procedura, ale trzeba ją przejrzeć. Używa wszystkich starych widoków sys. –

0

W SQL 200:

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

We wcześniejszych wersjach SQL Server, bazy danych może zawierać jednostka nazywa się "schemat", ale że jednostka była skutecznie użytkownik bazy danych.

1

tylko powtórzyć to, co już zostało tutaj zasugerował, oto co użyłem, aby uzyskać listę tabel, procedur przechowywanych, widoków i funkcji w mojej bazy danych:

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 

... i oto co Nasz dobry przyjaciel Northwind wróci ...

enter image description here

0

zawierało opcję, aby usunąć wszystkie obiekty zaczynające się od pewnej prefiksu i ewentualnie z pewnego schematu. Przy okazji dodałem dodatkowe zapytanie, aby uzyskać wszystkie typy, które nie są domyślnie przechowywane na sysobjects.

Wysłałem całą przykładowy skrypt do GitHub: DropAll_Dnn_Objects.sql

Część 1: Tymczasowe procedury przechowywanej:

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 

Będzie nadal na błędy (i wyświetli komunikat o błędzie). Zwróci liczbę znalezionych obiektów.

Część 2: Call procedury przechowywanej z parametrami:

Można tworzyć pętli while w celu uruchomienia polecenia, dopóki nie obiekt jest w lewo (w zależności), w następujący sposób:

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 : W końcu, pozbyć się procedury:

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