6

AとBの2つの列を持つmysqlテーブルがあるとします。AまたはBのいずれかに1回だけ(テーブル全体で1回)値を挿入できるように、一意のキーを持つことは可能ですか?

したがって、列Aに「qwe」が含まれ、Bに「asd」が含まれている場合、これら2つの値をどちらの列にも挿入できなくなります。

これは機能しません:

UNIQUE KEY `A` (`A`,`B`),
UNIQUE KEY `A_2` (`A`),
UNIQUE KEY `B` (`B`),
UNIQUE KEY `B_2` (`B`,`A`)

ありがとう。

編集:私は次のトリガーでこれを達成することができました:

delimiter |
create trigger unique_check before insert on mytable
       for each row begin
              declare alreadyexists integer;
          select count(*) > 0 into alreadyexists from mytable
                 where A=NEW.B or B=NEW.A;
          IF alreadyexists = 1 THEN begin
             DECLARE dummy INT;
         SELECT 'A OR B already exists' INTO dummy FROM mytable
            WHERE nonexistent = 'value';
 end;
 END IF;
 END;|

ただし、「A OR Bはすでに存在します」というエラーメッセージは表示されませんが、次のようになります。

エラー1054(42S22):「where句」に不明な列「存在しません」

再度、感謝します!

4

3 に答える 3

2

はい、可能です。

1つの方法は

BEFORE INSERT値が他の列/テーブルですでに見つかっている場合は、TRIGGERを作成してエラーを返す必要があります。

このブログ投稿から

MySQLトリガー:トリガーを使用してINSERT、UPDATE、またはDELETEをどのように中止しますか?EfNetの#mysqlで誰かが尋ねました:

ビジネスルールが失敗した場合、トリガーで操作を中止するにはどうすればよいですか?

MySQL 5.0および5.1では、トリガーを失敗させて意味のあるエラーメッセージを配信するために、いくつかのトリックに頼る必要があります。MySQLストアドプロシージャFAQには、エラー処理について次のように記載されています。

SP 11. SPには、「アプリケーションエラーを発生させる」ための「発生」ステートメントがありますか?申し訳ありませんが、現時点ではありません。SQL標準のSIGNALおよびRESIGNALステートメントはTODOにあります。

おそらく、MySQL 5.2には、このハックがMySQLストアドプロシージャプログラミングから直接盗まれるSIGNALステートメントが含まれるでしょう。ハックとは何ですか?存在しない列の使用をMySQLに強制します。ぶさいくな?はい。それは機能しますか?もちろん。

CREATE TRIGGER mytabletriggerexample
BEFORE INSERT
FOR EACH ROW BEGIN
IF(NEW.important_value) < (fancy * dancy * calculation) THEN
    DECLARE dummy INT;

    SELECT Your meaningful error message goes here INTO dummy 
        FROM mytable
      WHERE mytable.id=new.id
END IF; END;

別の方法

あなたもすることができますTransactions

トランザクションを含むプロシージャを使用して、データをトランザクションテーブル(InnoDB)に挿入します。

トリガー書き込みエラー状態:

set @error=1; 

手順では、次のようになります。

set @error=0; 
start transaction 
do insert 
if @error>0 then rollback; 
else commit; 
于 2011-03-15T11:18:48.663 に答える
1

これをリレーショナルに行う適切な(そして簡単な)方法は、T1とT2の2つのテーブルを作成することです。ここで、T2はT1に対して(多対1の)外部キー関係を持っています。一意のインデックス/制約はT2.yourUniqueColumnで宣言されており、その列の値を区別する必要がある場合は、T2に別の列を追加します。

   T1
   id
   foo


   T2
   t2id
   t1id  fk references T1
   yourUniqueColumn  [unique index/constraint]
   extraColumnToDescribeTheValueInUniqueColumn     

最初は、次の方法でT2にデータを入力できます(T2でPKを自動インクリメントすると想定)。

  insert into T2
  (t1id, yourUniqueColumn, extraColumn)
  select t1.id as t1id, T1.A as yourUniqueColumn, 'A' as extraColumn from T1


  insert into T2
  (t1id, yourUniqueColumn, extraColumn)
  select T1.id as t1id, T1.B as yourUniqueColumn, 'B' as extraColumn from T1

経験則として、リレーショナルデータベースで作業しているときに手続き的に物事を行っていることに気付いたときはいつでも、一歩下がってリファクタリングを検討するときが来ました。

于 2011-03-15T11:37:01.880 に答える
0

COALESCEを使用して、AまたはBから最初のnull値を取得できます。ただし、両方が設定されていない場合はhttp://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce

于 2011-03-15T11:29:04.890 に答える