sql >> データベース >  >> RDS >> Sqlserver

データベース制約を使用したいが、削除ではなく削除済みとしてマークするだけの場合はどうすればよいですか?

    レコードが削除されたときに名前の末尾に id 値を追加できます。そのため、誰かが ID 3 を削除すると名前が Thingy3_3 になり、ID 100 を削除すると名前が Thingy3_100 になります。これにより、名前と削除されたフィールドに一意の複合インデックスを作成できますが、名前列を表示するたびにフィルターをかけ、名前の末尾から ID を削除する必要があります。

    おそらく、削除された列をDATETIME型のdeleted_at列に置き換えることがより良い解決策になるでしょう。次に、削除されていないレコードのdeleted_atフィールドにnull値があり、nameとdeleted atに一意のインデックスを維持できます。これにより、アクティブな状態で複数の名前を作成することはできなくなりますが、同じ名前を複数回削除することができます。

    削除を取り消す前に、同じ名前の行がなく、deleted_at フィールドが null であることを確認するために、レコードの削除を取り消すときに明らかにテストを行う必要があります。

    実際には、削除に INSTEAD-OF トリガーを使用して、データベース内にこのすべてのロジックを実装できます。このトリガーはレコードを削除しませんが、代わりに、レコードを削除したときに deleted_at 列を更新します。

    次のコード例はこれを示しています

    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  
    

    このクエリから選択すると、次が返されます

    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
    

    したがって、コード内で通常の削除を使用してレコードを削除し、トリガーに詳細を任せることができます。唯一の可能性のある問題 (私が見ることができた) は、既に削除されたレコードを削除すると行が重複する可能性があることでした。そのため、既に削除された行の deleted_at フィールドを更新しないトリガーの条件です。



    1. 主キーと外部キーの関係を作成する

    2. イベントのランダム加重選択

    3. mysqlデータベースの5桁の数字を日付に変換するだけです

    4. ODP.Net-OracleDataReader.Readが非常に遅い