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

MySQLの条件付き値チェックで制約する

    ドキュメント によると 、

    したがって、not nullを削除します -Statusからの制約 (ContactId,PhoneId,Status)に一意のインデックスを追加します nullを使用すると、希望どおりに機能します 0の代わりに 非アクティブの場合 記録。

    nullを使用したくないまたは使用できない場合 Status 列、両方のStatus=0を確認する必要があります およびStatus=null 同じように動作する、または例: Status=2を扱いたい アクティブとして (そして一意性を強制する)また、Statusから計算されるダミー列を追加することもできます 。

    MySQL 5.7以降を使用している場合は、生成された列を使用してこれを行うことができます:

    CREATE TABLE IF NOT EXISTS `ContactPhone` (
      `ContactPhoneId` int(10) unsigned NOT NULL auto_increment primary key,
      `ContactId` int(11) NOT NULL,
      `PhoneId` smallint(5) unsigned NOT NULL,
      `Status` tinyint(1) NOT NULL DEFAULT '1',
      `StatusUnq` tinyint(1) as (if(Status <> 0, 1, null)) stored null,
      constraint unique (ContactId, PhoneId, StatusUnq)
    ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
    
    insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
    values (1, 1, 1, 1);
    insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
    values (2, 1, 1, 1);
    -- Duplicate key error 
    insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
    values (3, 1, 1, 0);
    insert into ContactPhone (ContactPhoneId, ContactId, PhoneId, Status)
    values (4, 1, 1, 0);
    update ContactPhone set Status = 1 where ContactPhoneId = 4;
    -- Duplicate key error 
    

    それ以外の場合は、通常の列を使用し、トリガーを使用して列の値を計算できます(例:

    )。
    create trigger trbi_contactPhoneUnique before insert on ContactPhone 
    for each row
      set new.StatusUnq = if(new.Status <> 0, 1, null);
    
    create trigger trbu_contactPhoneUnique before update on ContactPhone 
    for each row
      set new.StatusUnq = if(new.Status <> 0, 1, null);
    

    もちろん、数式を次のように切り替えることもできます。 if(new.Status <> 0, new.Status, null); Statusの異なる値を許可する場合 それも。




    1. mySQL例外:指定されたMySQLホストのいずれにも接続できません。 C#を介して

    2. オブジェクトのネストされた配列を取得するための結合を使用したSQLクエリ

    3. 作成時のみのMySQLタイムスタンプ

    4. レコメンデーションエンジンデータベースの設計?