Di chuyển các bảng sang cơ sở dữ liệu SQL2008 khác (bao gồm các chỉ mục, trình kích hoạt, v.v.)


16

Tôi cần di chuyển cả đống (hơn 100) bảng lớn (hàng triệu hàng) từ cơ sở dữ liệu SQL2008 này sang cơ sở dữ liệu khác.

Ban đầu tôi chỉ sử dụng Trình hướng dẫn Nhập / Xuất, nhưng tất cả các bảng đích đều thiếu khóa chính, chỉ mục, ràng buộc, trình kích hoạt, v.v. (Các cột định danh cũng được chuyển đổi thành INT đơn giản, nhưng tôi nghĩ rằng tôi chỉ bỏ lỡ một hộp kiểm trong Thuật sĩ.)

Cách đúng đắn để làm điều này là gì?

Nếu đây chỉ là một vài bảng, tôi sẽ quay lại nguồn, tập lệnh ra định nghĩa bảng (với tất cả các chỉ mục, v.v.), sau đó chạy các phần tạo chỉ mục của tập lệnh ở đích. Nhưng với rất nhiều bảng, điều này có vẻ không thực tế.

Nếu không có quá nhiều dữ liệu, tôi có thể sử dụng thuật sĩ "Tạo tập lệnh ..." để tạo ra nguồn, bao gồm cả dữ liệu, nhưng tập lệnh 72m có vẻ không phải là một ý tưởng hay!


Và nó không phải là tất cả các bảng trong cơ sở dữ liệu?
thứ năm

@thursdaygeek: Gần như tất cả các bảng, nhưng cơ sở dữ liệu đích đã có hơn 100 bảng. Vì vậy, chỉ cần khôi phục từ bản sao lưu với một tên khác không phải là một lựa chọn. Hãy nghĩ về điều này về cơ bản là "hợp nhất hai cơ sở dữ liệu lớn này lại với nhau".
BradC

Câu trả lời:


14

Viết kịch bản ra các bảng, sau đó sử dụng SSIS để truyền dữ liệu sẽ là cách đáng tin cậy và hiệu quả nhất để di chuyển dữ liệu sang cơ sở dữ liệu mới.


9

Chúng tôi thực sự đã làm nó bằng cách sử dụng rất nhiều kịch bản thủ công kết hợp với Trình hướng dẫn nhập khẩu, nhưng sáng nay tôi đã tìm thấy một câu trả lời tốt hơn, nhờ vào bài viết trên blog của Tibor Karaszi .

Một phần của sự thất vọng của chúng tôi ở đây là "Trình hướng dẫn xuất / nhập DTS" của SQL 2000 thực sự làm cho việc này gần như dễ dàng bằng cách chọn "Sao chép đối tượng và dữ liệu":

Thuật sĩ nhập DTS

Tùy chọn thứ ba này là tùy chọn chứa khả năng bao gồm các chỉ mục / trình kích hoạt, v.v .:

Tùy chọn nâng cao

Tùy chọn này đã được xóa từ Trình hướng dẫn nhập khẩu SQL 2005/2008 . Tại sao? Không ý kiến:

Thuật sĩ nhập khẩu 2008

Vào năm 2005/2008, rõ ràng bạn phải tạo thủ công gói SSIS trong BIDS và sử dụng Tác vụ đối tượng máy chủ SQL chuyển , chứa tất cả các tùy chọn tương tự trong trình hướng dẫn 2000:

Nhiệm vụ đối tượng máy chủ SQL chuyển SSIS


Chỉ muốn đăng rằng tôi đã sử dụng phương pháp SSIS này cho một nhiệm vụ tương tự khác, và nó đã hoạt động rất tốt!
BradC

8

Tôi sẽ xem xét kịch bản ra bảng hoặc sử dụng một công cụ so sánh (ví dụ Cổng đỏ) để tạo các bảng trong cơ sở dữ liệu đích. Không có chỉ mục hoặc ràng buộc nào.

Sau đó, tôi sẽ xem xét khôi phục cơ sở dữ liệu với một tên khác trên cùng một máy chủ và thực hiện

 INSERT newdb.dbo.newtable SELECT * FROM olddb.dbo.oldtable

.. cho mỗi bảng, với TẮT ID IDENTITY ON nếu được yêu cầu

Sau đó, tôi sẽ thêm các chỉ mục và các ràng buộc sau khi tải dữ liệu.

Nó phụ thuộc vào mức độ thoải mái của bạn với SSIS (câu trả lời của mrdenny) hoặc nếu bạn thích SQL thô.


6

Tôi muốn thêm vào câu trả lời của ông Denny: Tập lệnh lược đồ bảng sau đó sử dụng BCP để di chuyển dữ liệu. Nếu bạn không quen thuộc với SSIS, thì việc sử dụng BCP và các đợt sẽ rất dễ thực hiện. Đối với hàng triệu hàng, không có gì vượt qua BCP (chèn số lượng lớn) :).


4

Tôi là người hoàn toàn không thoải mái với SSIS.

Khi các bảng nguồn không có cột định danh

  1. tạo một cơ sở dữ liệu trống tại máy chủ đích
  2. tạo một máy chủ được liên kết đến máy chủ nguồn trên máy chủ đích
  3. chạy tập lệnh bên dưới trên cơ sở dữ liệu nguồn để tạo các câu lệnh select * thành ...
  4. chạy tập lệnh được tạo từ cơ sở dữ liệu đích
  5. kịch bản khóa chính, chỉ mục, trình kích hoạt, chức năng và quy trình từ cơ sở dữ liệu nguồn
  6. tạo các đối tượng này bằng tập lệnh được tạo

Bây giờ T-SQL để tạo các câu lệnh Chọn * thành ...

SET NOCOUNT ON

declare @name sysname
declare @sql varchar(255)

declare db_cursor cursor for
select name from sys.tables order by 1
open db_cursor

fetch next from db_cursor into @name
while @@FETCH_STATUS = 0
begin
    Set @sql = 'select * into [' + @name + '] from [linked_server].[source_db].[dbo].[' + @name + '];'
    print @sql

    fetch next from db_cursor into @name
end

close db_cursor
deallocate db_cursor

Điều này tạo ra một dòng cho mỗi bảng để sao chép như

select * into [Table1] from [linked_server].[source_db].[dbo].[Table1];

Trong trường hợp các bảng chứa các cột định danh, tôi kịch bản các bảng bao gồm các thuộc tính nhận dạng và các khóa chính.

Tôi không sử dụng insert vào ... select ... bằng cách sử dụng máy chủ được liên kết trong trường hợp này, vì đây không phải là kỹ thuật hàng loạt. Tôi đang làm việc trên một số tập lệnh PowerShell tương tự như [câu hỏi SO 1 này , nhưng tôi vẫn đang xử lý lỗi. Các bảng thực sự lớn có thể gây ra lỗi bộ nhớ, vì toàn bộ bảng được tải vào bộ nhớ, trước khi nó được gửi qua SQLBulkCopy đến cơ sở dữ liệu.

Giải trí các chỉ số, vv tương tự như trường hợp trên. Lần này tôi có thể bỏ qua việc giải trí các phím chính.


Trong trường hợp các bảng chứa các cột định danh, bạn có thể thực hiện như trong câu hỏi này . Nó sẽ giúp bạn tiết kiệm một số công việc thủ công. Tôi vẫn thích các lô chèn / SSIS số lượng lớn, máy chủ được liên kết có thể không phải là một giải pháp tốt trên một mạng rộng.
Mary

1
@Marian Vui lòng xem tại dba.stackexchange.com/questions/297/ Khăn nếu bạn muốn quảng bá SSIS. Tôi đã không thử SSIS, nhưng Trình hướng dẫn Nhập khẩu cũng thất bại (bên cạnh máy chủ được liên kết).
bernd_k

Tôi sẽ giúp tôi rất vui, nhưng tôi không có sẵn hộp Oracle nào cho tôi. Dù sao, từ những gì tôi đã quản lý để đọc, không có nhà cung cấp nào hỗ trợ Oracle CLOB ..
Marian

Tôi với bạn về điều này - đôi khi tôi di chuyển dữ liệu, nhưng không bao giờ sử dụng SSIS.
AK

2

Bạn có thể sử dụng các công cụ so sánh so sánh các lược đồ và dữ liệu cơ sở dữ liệu và trước tiên đồng bộ hóa một lược đồ cơ sở dữ liệu trống với db gốc, để tạo tất cả các bảng.

Sau đó, đồng bộ hóa dữ liệu từ cơ sở dữ liệu gốc với cơ sở dữ liệu mới (tất cả các bảng đều ở đó, nhưng tất cả đều trống) để chèn các bản ghi vào các bảng

Tôi sử dụng ApexSQL DiffApexSQL Data Diff cho việc này, nhưng có những công cụ tương tự khác.

Điểm hay của quy trình này là bạn không thực sự phải đồng bộ hóa cơ sở dữ liệu bằng công cụ này, vì điều này có thể khá đau đớn đối với hàng triệu hàng.

Bạn chỉ có thể tạo một tập lệnh SQL INSERT INTO (đừng ngạc nhiên nếu đó là một số hợp đồng biểu diễn) và thực thi nó.

Vì các tập lệnh lớn thậm chí không thể được mở trong SQL Server Management Studio, tôi sử dụng sqlcmd hoặc osql


1

Như @mrdenny đã đề cập -

  1. kịch bản ra các bảng trước tiên với tất cả các Chỉ mục, FK, v.v. và tạo các bảng trống trong cơ sở dữ liệu đích.

Thay vì sử dụng SSIS, hãy sử dụng BCP để chèn dữ liệu

  1. bcp ra dữ liệu bằng cách sử dụng tập lệnh dưới đây. đặt SSMS ở Chế độ văn bản và sao chép đầu ra được tạo bởi tập lệnh bên dưới trong tệp bat.

    -- save below output in a bat file by executing below in SSMS in TEXT mode
    
    -- clean up: create a bat file with this command --> del D:\BCP\*.dat 
    
    select '"C:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe" ' /* path to BCP.exe */
        +  QUOTENAME(DB_NAME())+ '.' /* Current Database */
        +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'            
        +  QUOTENAME(name)  
        +  ' out D:\BCP\'  /* Path where BCP out files will be stored */
        +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_' 
        +  REPLACE(name,' ','') 
        + '.dat -T -E -SServerName\Instance -n' /* ServerName, -E will take care of Identity, -n is for Native Format */
    from sys.tables
    where is_ms_shipped = 0 and name <> 'sysdiagrams'                       /* sysdiagrams is classified my MS as UserTable and we dont want it */
    /*and schema_name(schema_id) <> 'unwantedschema'    */                             /* Optional to exclude any schema  */
    order by schema_name(schema_id)
  2. Chạy tệp bat sẽ tạo các tệp .dat trong thư mục mà bạn đã chỉ định.

  3. Chạy bên dưới tập lệnh trên

    --- Execute this on the destination server.database from SSMS.
    
    --- Make sure the change the @Destdbname and the bcp out path as per your environment.
    
    declare @Destdbname sysname
    set @Destdbname = 'destinationDB' /* Destination Database Name where you want to Bulk Insert in */
    select 'BULK INSERT ' 
    /*Remember Tables must be present on destination database */ 
    + QUOTENAME(@Destdbname) + '.' 
    + QUOTENAME(SCHEMA_NAME(SCHEMA_ID)) 
    + '.' + QUOTENAME(name) 
    + ' from ''D:\BCP\' /* Change here for bcp out path */ 
    + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') 
    + '.dat'' with ( KEEPIDENTITY, DATAFILETYPE = ''native'', TABLOCK )' 
    + char(10) 
    + 'print ''Bulk insert for ' + REPLACE(SCHEMA_NAME(schema_id), ' ', '') + '_' + REPLACE(name, ' ', '') + ' is done... ''' 
    + char(10) + 'go'
       from sys.tables
       where is_ms_shipped = 0
    and name <> 'sysdiagrams' /* sysdiagrams is classified my MS as UserTable and we dont want it */
    and schema_name(schema_id) <> 'unwantedschema' /* Optional to exclude any schema */
        order by schema_name(schema_id) 
  4. Chạy đầu ra bằng SSMS để chèn dữ liệu trở lại trong các bảng.

Đây là phương pháp bcp rất nhanh vì nó sử dụng chế độ Bản địa.

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.