Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Phải làm gì khi tôi muốn sử dụng các ràng buộc cơ sở dữ liệu nhưng chỉ đánh dấu là đã xóa thay vì xóa?

Bạn có thể thêm giá trị id vào cuối tên khi bản ghi bị xóa, vì vậy khi ai đó xóa id 3, tên sẽ trở thành Thingy3_3 và sau đó khi họ xóa id 100, tên sẽ trở thành Thingy3_100. Điều này sẽ cho phép bạn tạo một chỉ mục tổng hợp duy nhất trên tên và các trường đã xóa nhưng sau đó bạn phải lọc cột tên bất cứ khi nào bạn hiển thị nó và xóa id khỏi phần cuối của tên.

Có lẽ giải pháp tốt hơn sẽ là thay thế cột đã xóa của bạn bằng một cột delete_at kiểu DATETIME. Sau đó, bạn có thể duy trì một chỉ mục duy nhất trên tên và bị xóa tại, với một bản ghi không bị xóa có giá trị null trong trường delete_at. Điều này sẽ ngăn việc tạo nhiều tên ở trạng thái hoạt động nhưng sẽ cho phép bạn xóa cùng một tên nhiều lần.

Rõ ràng bạn cần thực hiện kiểm tra khi hủy xóa bản ghi để đảm bảo rằng không có hàng nào có cùng tên và trường null Delete_at trước khi cho phép hủy xóa.

Bạn thực sự có thể triển khai tất cả logic này trong cơ sở dữ liệu bằng cách sử dụng kích hoạt INSTEAD-OF để xóa. Trình kích hoạt này sẽ không xóa bản ghi mà thay vào đó sẽ cập nhật cột Delete_at khi bạn xóa bản ghi.

Đoạn mã ví dụ sau minh họa điều này

CREATE TABLE swtest (  
    id          INT IDENTITY,  
    name        NVARCHAR(20),  
    deleted_at  DATETIME  
)  
GO  
CREATE TRIGGER tr_swtest_delete ON swtest  
INSTEAD OF DELETE  
AS  
BEGIN  
    UPDATE swtest SET deleted_at = getDate()  
    WHERE id IN (SELECT deleted.id FROM deleted)
    AND deleted_at IS NULL      -- Required to prevent duplicates when deleting already deleted records  
END  
GO  

CREATE UNIQUE INDEX ix_swtest1 ON swtest(name, deleted_at)  

INSERT INTO swtest (name) VALUES ('Thingy1')  
INSERT INTO swtest (name) VALUES ('Thingy2')  
DELETE FROM swtest WHERE id = SCOPE_IDENTITY()  
INSERT INTO swtest (name) VALUES ('Thingy2')  
DELETE FROM swtest WHERE id = SCOPE_IDENTITY()  
INSERT INTO swtest (name) VALUES ('Thingy2')  

SELECT * FROM swtest  
DROP TABLE swtest  

Lựa chọn từ truy vấn này trả về kết quả sau

id      name       deleted_at
1       Thingy1    NULL
2       Thingy2    2009-04-21 08:55:38.180
3       Thingy2    2009-04-21 08:55:38.307
4       Thingy2    NULL

Vì vậy, trong mã của bạn, bạn có thể xóa các bản ghi bằng cách xóa thông thường và để trình kích hoạt xử lý các chi tiết. Vấn đề duy nhất có thể xảy ra (Điều đó tôi có thể thấy) là việc xóa các bản ghi đã bị xóa có thể dẫn đến các hàng trùng lặp, do đó, điều kiện trong trình kích hoạt để không cập nhật trường Delete_at trên một hàng đã bị xóa.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tham số đầu ra máy chủ PHP Sql

  2. Chọn các hàng trên cùng cho đến khi giá trị trong cột cụ thể xuất hiện hai lần

  3. Làm cách nào để tìm các ký tự Unicode / không phải ASCII trong trường NTEXT trong bảng SQL Server 2005?

  4. ràng buộc duy nhất có điều kiện

  5. Làm cách nào để nhập một cách chọn lọc XLS vào bảng SQL Server 2008?