Làm cách nào để di chuyển giữa các lược đồ hàng loạt trong SQL Server?


8

Chúng tôi hiện có nhiều cơ sở dữ liệu nhưng muốn kết hợp chúng và thay vào đó, phân tách bối cảnh miền bằng cách sử dụng lược đồ.

Trong MS SQL Server 2008 R2, làm cách nào tôi có thể di chuyển tất cả nội dung của một lược đồ này sang hàng loạt khác?

Ví dụ: tất cả các bảng, dạng xem, thủ tục, chỉ mục, v.v ... mà chúng ta đã tạo trong dbolược đồ sẽ tồn tại trong foolược đồ.

EDIT: Tôi muốn làm rõ dựa trên những bình luận tuyệt vời của AaronBertrand. Đây không phải là một tình huống nhiều người thuê nhà. Tình huống của chúng tôi là nơi các plugin công cụ nội bộ được phát triển một cách cô lập bởi các nhà phát triển đã không hợp nhất các bảng của họ vào cơ sở dữ liệu của công cụ.


2
Điều này có thể trở nên thực sự khó khăn với FK và các phụ thuộc khác. Tại sao bạn chuyển đổi mô hình? Tôi thích mô hình đa db hơn mô hình đa lược đồ vì nhiều lý do - xem dba.stackexchange.com/questions/33550/ Kẻdba.stackexchange.com/questions/16745/ tựa
Aaron Bertrand

@AaronBertrand trong số các lý do là chúng tôi có sự phụ thuộc quan hệ giữa các thực thể trong cơ sở dữ liệu riêng biệt (ví dụ: người dùng trong DB riêng của họ) và, đồng thời, chúng tôi có các chế độ xem trải rộng cơ sở dữ liệu và do đó không thể sử dụng lược đồ.
Matthew


Bạn không cần khóa ngoại để có mối quan hệ - chúng có thể được thực thi rõ ràng theo nhiều cách khác nhau. Và quan điểm của bạn không cần phải BẮT ĐẦU trừ khi chúng được lập chỉ mục. Tôi đã làm việc với một hệ thống như vậy trong 13 năm và tôi có thể hứa với bạn rằng những điều bạn lo lắng không đáng lo ngại so với những thứ bạn sẽ mất bằng cách kết hợp mọi người vào một cơ sở dữ liệu.
Aaron Bertrand

@AaronBertrand sự khác biệt lớn mà tôi thấy giữa trường hợp sử dụng của tôi và điều thường được mô tả trong liên kết của bạn là các cơ sở dữ liệu này không tách rời khách hàng hoặc người thuê nhà theo bất kỳ cách nào. Mỗi người trong số họ được sử dụng bởi sự kết hợp của các công cụ nội bộ. Có khả năng lý do chúng tách biệt là do nhà phát triển tạo plugin công cụ trong chân không sau đó gắn nó mà không hợp nhất vào DB chính. Chúng tôi thực sự sẽ có các DB riêng biệt để đối phó với việc thuê nhà và các môi trường khác nhau ...
Matthew

Câu trả lời:


9

Khái niệm cơ bản thực sự khá đơn giản: bạn tạo một tập lệnh từ đó sys.objectssys.schemasxây dựng các ALTER SCHEMA TRANSFERcâu lệnh. Vì vậy, ví dụ, bạn có ba đối tượng trong dbolược đồ và bạn muốn di chuyển tất cả chúng vào blatlược đồ:

Table: dbo.foo
Table: dbo.bar
View:  dbo.vFooBar

Các mã sau đây:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'
  ALTER SCHEMA blat TRANSFER dbo.' + QUOTENAME(o.name) + ';'
FROM sys.objects AS o
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
WHERE s.name = N'dbo';

PRINT @sql;
-- EXEC sp_executesql @sql;

Sẽ mang lại kịch bản này (nhưng có lẽ không theo thứ tự này):

ALTER SCHEMA blat TRANSFER dbo.bar;
ALTER SCHEMA blat TRANSFER dbo.foo;
ALTER SCHEMA blat TRANSFER dbo.vFooBar;

(Bạn có thể muốn thêm các bộ lọc bổ sung để loại bỏ các đối tượng trong dbolược đồ mà bạn không muốn di chuyển, loại bỏ một số loại đối tượng nhất định (ví dụ: có thể tất cả các chức năng của bạn là các hàm tiện ích và không cần phải di chuyển), tạo tập lệnh được sắp xếp theo loại đối tượng, v.v.)

Nhưng có một vài vấn đề với việc di chuyển tất cả các đối tượng của bạn sang một lược đồ mới:

  1. Có lẽ rất nhiều mã của bạn vẫn sẽ tham chiếu các đối tượng này như dbo.object- không có cách nào dễ dàng để sửa lỗi này ngoại trừ lực lượng vũ phu. Bạn có thể có thể tìm thấy tất cả các lần xuất hiện dbo.khá dễ dàng, nhưng những điều này cũng có thể trả về các kết quả dương tính giả, chẳng hạn như EXEC dbo.sp_executesql, dbo.trong các bình luận, các tham chiếu thực sự cho các đối tượng vẫn còn trong dbo.lược đồ, v.v.

  2. Sự phụ thuộc của bạn có thể sẽ hoàn toàn vượt qua, nhưng tôi chưa kiểm tra kỹ điều này. Tôi biết rằng trong kịch bản này:

    CREATE SCHEMA blat AUTHORIZATION dbo;
    GO
    
    CREATE TABLE dbo.foo(a INT PRIMARY KEY);
    CREATE TABLE dbo.bar(a INT FOREIGN KEY REFERENCES dbo.foo(a));
    GO
    
    CREATE PROCEDURE dbo.pX AS
    BEGIN
      SET NOCOUNT ON;
      SELECT a FROM dbo.bar;
    END
    GO
    
    CREATE VIEW dbo.vFooBar
    AS
      SELECT foo.a, bar.a AS barA
        FROM dbo.foo 
        INNER JOIN dbo.bar
        ON foo.a = bar.a;
    GO
    
    ALTER SCHEMA blat TRANSFER dbo.foo;
    ALTER SCHEMA blat TRANSFER dbo.bar;
    ALTER SCHEMA blat TRANSFER dbo.pX;
    ALTER SCHEMA blat TRANSFER dbo.vFooBar;

    Các khóa ngoại thực sự di chuyển trơn tru hơn tôi mong đợi (với lời cảnh báo mà tôi đang thử nghiệm trên phiên bản gần đây hơn nhiều so với bạn). Nhưng vì mã trong blat.pXtham chiếu vẫn còn dbo.bar, rõ ràng đang thực hiện thủ tục:

    EXEC blat.pX;

    Sẽ mang lại lỗi này:

    Msg 208, Cấp 16, Trạng thái 1, Quy trình pX
    Tên đối tượng không hợp lệ 'dbo.bar'.

    Và các truy vấn phụ thuộc, chẳng hạn như:

    SELECT * FROM sys.dm_sql_referenced_entities('blat.pX', N'OBJECT');

    Sẽ mang lại lỗi này:

    Msg 2020, Cấp 16, Trạng thái 1
    Các phụ thuộc được báo cáo cho thực thể "blat.pX" có thể không bao gồm các tham chiếu đến tất cả các cột. Điều này là do thực thể tham chiếu một đối tượng không tồn tại hoặc do lỗi trong một hoặc nhiều câu lệnh trong thực thể. Trước khi chạy lại truy vấn, đảm bảo rằng không có lỗi trong thực thể và tất cả các đối tượng được tham chiếu bởi thực thể tồn tại.

    Và truy vấn khung nhìn:

    SELECT a, barA FROM blat.vFooBar;

    Mang lại những lỗi này:

    Msg 208, Cấp 16, Trạng thái 1, Quy trình vFooBar
    Tên đối tượng không hợp lệ 'dbo.foo'.
    Msg 4413, Cấp 16, Trạng thái 1
    Không thể sử dụng chế độ xem hoặc chức năng 'blat.vFoobar' vì lỗi liên kết.

    Vì vậy, điều này có thể liên quan đến rất nhiều dọn dẹp. Và sau khi bạn đã sửa tất cả các tham chiếu đối tượng, có thể bạn sẽ muốn biên dịch lại tất cả các mô-đun và làm mới tất cả các khung nhìn trong lược đồ mới. Bạn có thể tạo một tập lệnh cho điều đó khá giống với ví dụ trên.


+1, có vẻ như tôi cần bỏ thủ công một số FK để thực hiện chuyển khoản này ... Tôi không biết nguyên nhân nào gây ra điều đó
Matthew

@Matthew yeah, nếu các khóa ngoại gây rắc rối cho bạn, hãy xem câu trả lời này - bạn sẽ chỉ cần điều chỉnh nó để phần tạo lại của tập lệnh tham chiếu lược đồ mới.
Aaron Bertrand

@Matthew bạn đã tìm ra tình huống nào tồn tại để ngăn các bảng nhất định có khóa ngoại chuyển trơn tru chưa? Thông báo lỗi chính xác mà bạn nhận được là gì? Thật thú vị khi biết liệu bạn có thể bỏ qua điều đó bằng cách vô hiệu hóa ràng buộc hơn là bỏ nó đi ... nhưng tôi rất khó kiểm tra vì tôi không biết trình chặn chính xác của bạn là gì.
Aaron Bertrand
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.