2009-05-27 24 views
26

Làm thế nào để tôi nhận được SCHEMA khi thực hiện lựa chọn trên sysobject?Máy chủ SQL - Trả về SCHEMA cho sysobjects

Tôi đang sửa đổi quy trình được lưu trữ được gọi là SearchObjectsForText chỉ trả về Tên nhưng tôi cũng muốn bao gồm SCHEMA.

Ngay bây giờ nó đang làm một cái gì đó tương tự như sau:

SELECT DISTINCT name 
FROM sysobjects 

Tôi muốn biết những gì bảng cần phải được tham gia trả lại Đề án cho mỗi 'name'.

Trả lời

53

Nếu bạn có nghĩa là SQL Server 2005 hoặc cao hơn, sử dụng sys.objects thay vì 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 giới thiệu lược đồ. đến năm 2000, người dùng đã cân bằng các lược đồ. Truy vấn tương tự cho SQL Server 2000:

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

Do bố cục của thủ tục lưu trữ SearchObjectsForText tôi đã kết thúc bằng phương pháp này. Nhưng tôi cũng thích "khoa học dây" bởi vì nó đơn giản hơn nhiều. –

+0

Điều đáng nói là điều này sẽ * không * cho kết quả tương tự. Ví dụ, sysobjects sẽ trả về các khung nhìn danh mục hệ thống trong khi sys.objects không –

4

Thay vào đó, bạn có thể sử dụng Information_Schema view(s)?

SELECT DISTINCT table_name, table_schema 
FROM INFORMATION_SCHEMA.TABLES 

Theo the MSDN page (cho SQL Server 2008 trở lên),

Không sử dụng quan điểm INFORMATION_SCHEMA để xác định lược đồ của một đối tượng. Cách đáng tin cậy duy nhất để tìm lược đồ của một đối tượng là truy vấn khung nhìn danh mục sys.objects.

Tuy nhiên, có vẻ như chúng có thể đề cập đến vấn đề bạn có tên bảng và đang cố gắng tìm giản đồ của nó, điều này sẽ không hoạt động nếu có nhiều bảng có cùng tên. lược đồ). Nếu bạn đang truy vấn nhiều kết quả (không chỉ cố gắng tìm giản đồ cho một bảng cụ thể), thì nó sẽ ổn thôi.

+0

Tôi ước gì có thể nhưng tôi không muốn thay đổi thủ tục lưu trữ hiện tại thành nhiều và chỉ thực hiện một phép nối sẽ dễ dàng hơn. Cảm ơn bạn đã đề xuất. Tôi đã cho bạn một cuộc bỏ phiếu cho nó. :) –

+6

Không sử dụng các khung nhìn INFORMATION_SCHEMA để xác định lược đồ của một đối tượng? Lời thề! Đối với tôi, âm thanh này giống như một lỗi phải được sửa, không giống như một tính năng được ghi lại trong MSDN. Nếu bạn đồng ý, hãy đảm bảo gửi phản hồi trên trang MSDN. –

+1

@ Alex Tôi hoàn toàn chắc chắn rằng "xác định giản đồ của một đối tượng" có nghĩa là, được đưa ra một tên bảng (hoặc id đối tượng), tìm ra lược đồ của nó là gì. Và có, nó không phải là đáng tin cậy để làm điều này với các khung nhìn INFORMATION_SCHEMA vì các khung nhìn information_schema không để lộ id đối tượng và vì vậy chỉ biết tên bảng, có thể có nhiều bảng theo tên đó, trong nhiều lược đồ. Iff bạn chỉ liệt kê danh sách các đối tượng với các lược đồ và tên của chúng, hoàn toàn an toàn khi sử dụng các khung nhìn INFORMATION_SCHEMA. Lưu ý rằng bạn có thể sử dụng các hàm hệ thống trên các id đối tượng để trả về các tên lược đồ. – ErikE

14

Mở Sql Server 2005 (và cao hơn), bạn có thể sử dụng sys.objects xem:

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

trong SQL Server 2000 (và dưới đây), "giản đồ" có một ý nghĩa khái niệm khác nhau. Lưu ý từ MSDN:

Trong bản phát hành trước của SQL Server, cơ sở dữ liệu có thể chứa thực thể được gọi là "lược đồ", nhưng thực thể đó là người dùng cơ sở dữ liệu hiệu quả. SQL Server 2005 là bản phát hành đầu tiên của SQL Server trong đó một lược đồ là cả một vùng chứa và một vùng tên.

3

Tôi muốn sử dụng chế độ xem "sys" tập trung hơn - sys.procedures thay vì sys.objects. Bạn sẽ cần phải kết hợp nó với khung nhìn sys.schemas để lấy tên lược đồ và như vậy.

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 

Tôi sẽ bắt đầu để tránh xa sử dụng "sysobjects" kể từ khi Microsoft nêu rõ trong Books Online rằng "sysobjects" là tùy thuộc vào loại bỏ trong một thông cáo trong tương lai:

SQL này Server 2000 hệ thống bảng là được bao gồm dưới dạng chế độ xem cho tính tương thích ngược. Chúng tôi khuyên bạn nên sử dụng chế độ xem hệ thống SQL Server hiện tại để thay thế. Để tìm giao diện hoặc khung nhìn hệ thống tương đương, hãy xem Ánh xạ các bảng hệ thống SQL Server 2000 đến các khung nhìn hệ thống SQL Server 2005. Tính năng này sẽ bị xóa trong phiên bản tương lai của Microsoft SQL Server.Tránh sử dụng tính năng này trong công việc phát triển mới và có kế hoạch sửa đổi các ứng dụng hiện đang sử dụng tính năng này.

Marc

+0

Cảm ơn ý tưởng. Đó là một thủ tục khá lớn nhưng thủ tục đó sẽ phải được xem xét lại. Nó đang sử dụng tất cả các khung nhìn cũ của sys. –

0

Trong SQL 200:

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

Trong phiên bản trước của SQL Server, cơ sở dữ liệu có thể chứa một thực thể được gọi là một "sơ đồ", nhưng thực thể đó là một cách hiệu quả một người sử dụng cơ sở dữ liệu.

1

Chỉ cần lặp lại những gì đã được đề xuất ở đây, đây là những gì tôi đã được sử dụng, để có được một danh sách các bảng, các Stored Procedure, xem và chức năng trong cơ sở dữ liệu của tôi:

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 

... và đây là những gì người bạn tốt của chúng tôi Northwind sẽ quay trở lại ...

enter image description here

0

đã bao gồm một tùy chọn để xóa tất cả các đối tượng bắt đầu với tiền tố nhất định và tùy chọn từ giản đồ nhất định. Nhân tiện, tôi đã thêm truy vấn phụ để nhận tất cả các loại không được lưu trữ trên sysobject theo mặc định.

Tôi đã tải lên toàn bộ kịch bản mẫu để GitHub: DropAll_Dnn_Objects.sql

Phần 1: Tạm 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 

Nó sẽ tiếp tục về lỗi (và hiển thị các thông báo lỗi). Nó sẽ trả về tổng số của tất cả các đối tượng được tìm thấy.

Phần 2: Gọi Stored Procedure với các thông số:

Bạn có thể tạo ra một vòng lặp while để chạy lệnh cho đến khi không có đối tượng còn lại (phụ thuộc), như sau:

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 

Phần 3 : Cuối cùng, hãy loại bỏ quy trình:

IF OBJECT_ID('_temp_DropAllDnnObjects') IS NOT NULL 
    DROP PROCEDURE _temp_DropAllDnnObjects; 
GO 
Các vấn đề liên quan