ghi đè bảng với dữ liệu từ bảng khác - SQL


9

Người dùng của chúng tôi muốn làm mới cơ sở dữ liệu QA từ sản xuất nhưng muốn có hai bảng (hãy gọi chúng là T1 và T2) để giữ lại dữ liệu QA gốc. Vì vậy, tôi đã sao chép hai bảng từ QA (DB1) sang cơ sở dữ liệu QA tạm thời (DB2). Sau đó làm mới DB1 từ sản xuất. Sau khi làm mới, tôi muốn ghi đè dữ liệu T1 và T2 từ DB2 sang DB1 để nó có thể chứa các giá trị QA được làm mới trước.

Tôi đã làm như sau:

  1. Sử dụng

    select * 
    INTO D1.dbo.T1
    FROM D2.dbo.T1
  2. Sau đó làm mới D1 từ prod

  3. Sau đó cắt ngắn T1 với bước sau:

    SELECT COUNT(*) AS BeforeTruncateCount
    FROM T1;
    GO
    TRUNCATE TABLE T1;
    GO
    SELECT COUNT(*) AS AfterTruncateCount
    FROM T1;
    GO
  4. Bây giờ khi tôi quay lại sao chép dữ liệu từ D2.T1 sang D1.T1, tôi nhận được lỗi rằng đã có một đối tượng có tên là T1 trong cơ sở dữ liệu.

Tôi có nên bỏ bảng và sao chép?

Hoặc có phương pháp nào tốt hơn cho toàn bộ thủ tục?

Câu trả lời:


6

Để kết hợp các câu trả lời từ @Kin và @DavidSpillett.

Đầu tiên một giả định. DB1 và ​​DB2 là cùng một ví dụ. Nghe có vẻ giống như họ nhưng không bao giờ đau lòng khi nói rõ ràng (đặc biệt là vì tôi đã sai với những gì tôi nghĩ là rõ ràng trước đây).

Cho rằng, nếu dữ liệu lớn, giả sử nhiều triệu hàng thì sử dụng gói SSIS. Điều này có một tính năng cụ thể mà bạn sẽ muốn sử dụng. Bạn có thể chỉ định một kích thước lô. Bằng cách này, kích thước giao dịch của bạn sẽ nhỏ hơn. Nhược điểm của gói SSIS là nó tăng thêm mức độ phức tạp cho quy trình của bạn. Nó không phải là một cái lớn, nhưng nếu bạn đang làm việc với một bảng nhỏ hơn, bạn không cần nó.

Điều này dẫn chúng ta đến lựa chọn khác. Tuy nhiên, nếu dữ liệu nằm trong phạm vi vài trăm nghìn hoặc nhỏ hơn thì hãy sử dụng mã như thế này.

USE D1;
GO
TRUNCATE TABLE dbo.T1;
GO
INSERT INTO D1.dbo.T1
SELECT * 
FROM D2.dbo.T1;
GO

Và cuối cùng nhưng không kém phần quan trọng nếu nó ở đâu đó trên tàu thì tôi sẽ thử cả hai và xem cái gì phù hợp nhất với bạn.

LƯU Ý: Bạn cũng có thể cân nhắc việc không sử dụng a SELECT *trên INSERT INTOvà thay vào đó chỉ định danh sách trường.

Cấu trúc đó sẽ trông như thế này

INSERT INTO D1.dbo.T1 (Field1, Field2)
SELECT Field1, Field2
FROM D2.dbo.T1;

Cảm ơn bạn về thông tin. Có, bảng chỉ có 7800 hàng nên khá nhỏ và trên cùng một ví dụ. Tôi đã thử sử dụng INSERT INTO (không chọn) và nó hoạt động hoàn hảo. Cảm ơn bạn đã chia sẻ điều này. Ngoài ra tôi đã thử nghiệm với Nhập dữ liệu với SSMS. Điều đó cũng làm việc rất tốt.
Rizwan

1
Lưu ý rằng bạn sẽ cần chỉ định danh sách trường (và không sử dụng *) nếu có trường thụt lề trong bảng - những giá trị đó không thể được "sao chép".
Conrad

6

IIRC với SELECT <stuff> INTO <target> FROM ...cú pháp SQL Server luôn cho rằng bạn muốn tạo bảng đích từ đầu. Khi bảng đã tồn tại, hãy thử INSERT <target> SELECT <stuff> FROM ...thay thế.


5
Ngoài ra, câu trả lời của David cũng là tuyến đường tốt hơn so với DROP và CHỌN VÀO khi di chuyển dữ liệu trở lại D1, bởi vì nếu bạn bỏ các bảng D1, bạn sẽ mất bất kỳ đối tượng con nào (ví dụ: khóa ngoại, khóa chính, trình kích hoạt, v.v. )
Delux

2
Tôi đồng ý với @Delux. Một điều quan trọng khác mà bạn sẽ mất là quyền rõ ràng. Nếu người dùng có các quyền cụ thể cho bảng đó (chứ không phải nói db_datareader) thì nếu bạn bỏ bảng thì bạn sẽ mất các quyền đó.
Kenneth Fisher

Đó là một mẹo tuyệt vời. Tôi đã không hiểu sự phân nhánh của DROP cho đến bây giờ. Cảm ơn bạn!
Rizwan

6

Tốt nhất là sử dụng SSIS (Nhập / xuất dữ liệu) để làm điều này. Nó có chức năng chỉ cần chuyển các bảng được chọn từ nguồn đến đích. Tùy chọn, bạn thậm chí có thể lưu gói để có thể được sử dụng lại cho các lần chuyển tiếp / lặp lại trong tương lai.

EDIT: Thêm nhiều ảnh chụp màn hình cho rõ ràng.

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


wow .. cảm ơn bạn vì những bức ảnh chụp màn hình tuyệt vời .. chúng là một sự trợ giúp tuyệt vời
Rizwan

Giải pháp tuyệt vời, ảnh chụp màn hình đẹp!
Mayer Spitzer
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.