2009-05-27 18 views
26

sysobjects पर चयन करते समय मुझे SCHEMA कैसे प्राप्त करें?SQL सर्वर - sysobjects के लिए वापसी SCHEMA

मैं नामक संग्रहीत प्रक्रिया को संशोधित कर रहा हूं जिसे SearchObjectsForText जो केवल नाम देता है लेकिन मैं SCHEMA भी शामिल करना चाहता हूं।

अभी यह इस के समान कुछ कर रहा है:

SELECT DISTINCT name 
FROM sysobjects 

मैं पता है कि टेबल प्रत्येक 'नाम' के लिए योजना वापस जाने के लिए शामिल हो गए करने की आवश्यकता चाहते हैं।

उत्तर

53

आप SQL सर्वर 2005 या उच्चतर मतलब हैं, तो sysobjects के बजाय 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 तक, उपयोगकर्ताओं ने स्कीमा के बराबर किया। एसक्यूएल सर्वर 2000 के लिए समान क्वेरी:

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

SearchObjectsForText संग्रहीत प्रक्रिया के लेआउट के कारण मैं इस विधि का उपयोग कर समाप्त हुआ। लेकिन मुझे "तार विज्ञान" भी पसंद आया क्योंकि यह बहुत आसान था। –

+0

यह इंगित करने लायक है कि यह * एक ही परिणाम नहीं देगा। उदाहरण के लिए, sysobjects सिस्टम कैटलॉग दृश्य वापस कर देगा, जबकि sys.objects –

4

आप Information_Schema view(s) बजाय का उपयोग कर सकते हैं?

SELECT DISTINCT table_name, table_schema 
FROM INFORMATION_SCHEMA.TABLES 

the MSDN page (एसक्यूएल सर्वर 2008 और इसके बाद के संस्करण के लिए) के अनुसार,

INFORMATION_SCHEMA दृश्यों का उपयोग एक वस्तु का स्कीमा निर्धारित करने के लिए न करें। ऑब्जेक्ट की स्कीमा खोजने का एकमात्र विश्वसनीय तरीका sys.objects कैटलॉग व्यू से पूछताछ करना है।

हालांकि, यह है कि वे शायद एक मुद्दा है जहाँ आप एक तालिका नाम है की चर्चा करते हुए कर रहे हैं और जो अगर वहाँ एक ही नाम के साथ कई तालिकाओं थे कार्य नहीं करेगा, अपने स्कीमा खोजने की कोशिश कर रहे हैं (विभिन्न में लगता है स्कीमा)। यदि आप कई परिणामों के लिए पूछताछ कर रहे हैं (केवल एक विशिष्ट तालिका के लिए स्कीमा खोजने की कोशिश नहीं कर रहे हैं), तो यह ठीक होना चाहिए।

+0

मेरी इच्छा है कि मैं कर सकता हूं लेकिन मैं मौजूदा संग्रहीत प्रक्रिया को बहुत अधिक नहीं बदलना चाहता हूं और केवल एक जोड़ना आसान होगा। वैसे भी सुझाव के लिए धन्यवाद। मैंने आपको इसके लिए एक वोट दिया। :) –

+6

किसी ऑब्जेक्ट की स्कीमा निर्धारित करने के लिए INFORMATION_SCHEMA दृश्यों का उपयोग न करें? वाह! मेरे लिए यह एक बग की तरह लगता है जिसे ठीक किया जाना चाहिए, एमएसडीएन में प्रलेखित फीचर की तरह नहीं। यदि आप सहमत हैं, तो एमएसडीएन साइट पर फीडबैक जमा करना सुनिश्चित करें। –

+1

@ एलेक्स मैं बिल्कुल निश्चित हूं कि "ऑब्जेक्ट की स्कीमा निर्धारित करना" का मतलब है, एक टेबल नाम (या ऑब्जेक्ट आईडी) दिया गया है, यह पता लगाने के लिए कि इसकी स्कीमा क्या है। और हां, यह INFORMATION_SCHEMA विचारों के साथ ऐसा करने के लिए विश्वसनीय नहीं है क्योंकि info_schema विचार ऑब्जेक्ट आईडी का पर्दाफाश नहीं करते हैं और इसलिए केवल तालिका का नाम जानना, कई नामों के तहत उस नाम से कई टेबल हो सकते हैं। यदि आप केवल अपनी स्कीमा और नामों के साथ वस्तुओं की सूची का आकलन कर रहे हैं, तो यह INFORMATION_SCHEMA विचारों का उपयोग करने के लिए पूरी तरह से सुरक्षित है। ध्यान दें कि आप स्कीमा नामों को वापस करने के लिए ऑब्जेक्ट आईडी पर सिस्टम फ़ंक्शंस का भी उपयोग कर सकते हैं। – ErikE

14

Sql सर्वर 2005 (और ऊपर) आप sys.objects उपयोग कर सकते हैं पर देखने:

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

Sql सर्वर 2000 (और नीचे) में, "स्कीमा" एक अलग वैचारिक अर्थ था। एमएसडीएन से नोट:

SQL सर्वर के पहले रिलीज़ में, डेटाबेस में "स्कीमा" नामक एक इकाई हो सकती है, लेकिन वह इकाई प्रभावी रूप से डेटाबेस उपयोगकर्ता थी। एसक्यूएल सर्वर 2005 एसक्यूएल सर्वर की पहली रिलीज है जिसमें एक स्कीमा एक कंटेनर और नामस्थान दोनों है।

3

मैं sys.objects के बजाय अधिक केंद्रित "sys" विचारों - sys.procedures का उपयोग करने का पक्ष लेगा। स्कीमा नाम और ऐसे प्राप्त करने के लिए आपको 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" एक भविष्य के रिलीज में निकाले जाने के अधीन है शुरू होगा:

यह एसक्यूएल सर्वर 2000 सिस्टम तालिका है पिछड़े संगतता के लिए एक दृश्य के रूप में शामिल किया गया। हम अनुशंसा करते हैं कि आप इसके बजाय वर्तमान SQL सर्वर सिस्टम दृश्यों का उपयोग करें। समकक्ष सिस्टम दृश्य या दृश्य ढूंढने के लिए, SQL Server 2005 सिस्टम दृश्यों में SQL Server 2000 सिस्टम टेबल्स मैपिंग देखें। यह सुविधा माइक्रोसॉफ्ट एसक्यूएल सर्वर के भविष्य के संस्करण में हटा दी जाएगी।इस सुविधा का उपयोग नए विकास कार्यों में करने से बचें, और वर्तमान में इस सुविधा का उपयोग करने वाले अनुप्रयोगों को संशोधित करने की योजना बनाएं।

मार्क

+0

विचार के लिए धन्यवाद। यह एक बहुत बड़ी प्रक्रिया है लेकिन एक की समीक्षा की जानी चाहिए। यह सभी पुराने sys विचारों का उपयोग कर रहा है। –

0

एसक्यूएल 200 में:

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

SQL सर्वर के पहले के रिलीज में, डेटाबेस को रख सकती एक इकाई एक "स्कीमा" कहा जाता है, लेकिन उस इकाई को प्रभावी ढंग से एक डेटाबेस उपयोगकर्ता था।

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: मानकों के साथ प्रक्रिया संग्रहित कॉल:

आप इस प्रकार आदेश आदेश को चलाने के लिए थोड़ी देर के पाश बना सकते हैं जब तक कि कोई वस्तु (निर्भरता) छोड़ दिया है,:

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 
संबंधित मुद्दे