2009-05-27 75 views
26

如何在sysobjects上進行選擇時獲取SCHEMA?SQL Server - 爲sysobjects返回SCHEMA

我在修改名爲的存儲過程SearchObjectsForText,它只返回名稱,但我還想包含SCHEMA。

現在它正在做一些與此類似:

SELECT DISTINCT name 
FROM sysobjects 

我想知道需要連接到返回該計劃對每個「名」是什麼表。

回答

53

如果你的意思是SQL Server 2005或更高,使用sys.objects中,而不是系統對象的:

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 
+0

由於SearchObjectsForText存儲過程的佈局,我最終使用此方法。但我也喜歡「線科學」,因爲它更簡單。 – 2009-05-28 13:18:04

+0

值得指出的是,這將*不*給出相同的結果。例如,sysobjects會返回系統目錄視圖,而sys.objects不會 – 2011-07-30 01:38:24

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目錄視圖。

但是,似乎他們可能指的是您有一個表名並正在嘗試查找其模式的問題,如果存在多個具有相同名稱的表(在不同的模式)。如果你正在查詢多個結果(不只是試圖找到特定表的模式),那麼它應該沒問題。

+0

我希望我可以但我不想更改現有的存儲過程,只是做一個連接會更容易。無論如何感謝您的建議。我給了你一個投票權。 :) – 2009-05-27 19:14:21

14

上的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

我希望使用更集中的「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 

我將開始使用「系統對象」脫身,因爲微軟聯機叢書中,明確指出「系統對象」是被遣返在未來的版本:

此SQL Server 2000系統表作爲向後兼容的視圖。我們建議您改用當前的SQL Server系統視圖。要查找等效的系統視圖,請參閱將SQL Server 2000系統表映射到SQL Server 2005系統視圖。此功能將在未來版本的Microsoft SQL Server中刪除。避免在新開發工作中使用此功能,並計劃修改當前使用此功能的應用程序。

馬克

0

在SQL 200:

​​

在SQL Server的早期版本,數據庫可以包含一個實體,稱爲 「模式」,但該實體是有效的數據庫用戶。

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 

...這是什麼我們的好朋友羅斯文將返回...

enter image description here

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