Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Apa yang harus dilakukan ketika saya ingin menggunakan batasan basis data tetapi hanya menandai sebagai dihapus alih-alih menghapus?

Anda dapat menambahkan nilai id ke akhir nama saat catatan dihapus, jadi ketika seseorang menghapus id 3, namanya menjadi Thingy3_3 dan kemudian ketika mereka menghapus id 100, namanya menjadi Thingy3_100. Ini akan memungkinkan Anda untuk membuat indeks komposit unik pada nama dan bidang yang dihapus tetapi Anda kemudian harus memfilter kolom nama setiap kali Anda menampilkannya dan menghapus id dari akhir nama.

Mungkin solusi yang lebih baik adalah mengganti kolom Anda yang dihapus dengan kolom delete_at bertipe DATETIME. Anda kemudian dapat mempertahankan indeks unik pada nama dan dihapus di, dengan catatan yang tidak dihapus memiliki nilai nol di bidang delete_at. Ini akan mencegah pembuatan beberapa nama dalam keadaan aktif tetapi akan memungkinkan Anda untuk menghapus nama yang sama beberapa kali.

Anda jelas perlu melakukan pengujian saat membatalkan penghapusan catatan untuk memastikan bahwa tidak ada baris dengan nama yang sama dan bidang null delete_at sebelum mengizinkan pembatalan penghapusan.

Anda benar-benar dapat menerapkan semua logika ini dalam database dengan menggunakan pemicu BUKAN-OF untuk penghapusan. Pemicu ini tidak akan menghapus catatan tetapi akan memperbarui kolom delete_at saat Anda menghapus catatan.

Kode contoh berikut menunjukkan ini

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  

Pilihan dari kueri ini mengembalikan yang berikut

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

Jadi di dalam kode Anda, Anda dapat menghapus catatan menggunakan penghapusan normal dan membiarkan pemicu menangani detailnya. Satu-satunya masalah yang mungkin (Yang dapat saya lihat) adalah bahwa menghapus catatan yang sudah dihapus dapat mengakibatkan baris duplikat, oleh karena itu kondisi di pemicu untuk tidak memperbarui bidang delete_at pada baris yang sudah dihapus.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pilih kolom yang tidak kosong menggunakan SQL Server

  2. Cara menentukan apakah instance SQL Server peka huruf besar-kecil atau tidak

  3. Cara Menggunakan Jadwal yang Sama untuk Beberapa Pekerjaan Agen SQL Server (T-SQL)

  4. SQL Server:PILIH hanya baris dengan MAX(DATE)

  5. Menghindari kursor untuk memperbarui banyak catatan menggunakan pemicu