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

1093MySQLテーブルのエラーが2回指定されました

    MySQLでは、同じテーブルをUPDATEまたはDELETEする同じステートメント内のテーブルからSELECTすることはできません。

    mysql> UPDATE ch_15_posts SET ID = (select MAX(ID)+1 as max FROM `ch_15_posts`) where id = 0;
    ERROR 1093 (HY000): You can't specify target table 'ch_15_posts' for update in FROM clause
    

    回避策 一種のdoublesubqueryを実行する これは、内部サブクエリを以前に評価し、結果を一時テーブルに格納します。ただし、これはサブサブクエリを1回だけ実行し、単一の値を生成してid =0のすべての行に割り当てるため、目的の結果は得られません。

    mysql> UPDATE ch_15_posts SET ID = (select max from (select MAX(ID)+1 as max FROM `ch_15_posts`) t) where id = 0;
    Query OK, 3 rows affected (0.02 sec)
    Rows matched: 3  Changed: 3  Warnings: 0
    

    誤って値0を設定した行に自動インクリメント値を割り当てようとしているようです。他の同時セッションが新しい行を挿入している可能性があるため、テーブルをロックせずにMAX(id)+1メソッドを使用することはできません。あなたがそれをしている間。つまり、競合状態です。

    ただし、列を自動インクリメントキーにすることで、自動インクリメント値をアトミックに埋め戻すことができます。

    デモ:

    mysql> create table c_15_posts (id int );
    
    mysql> insert into c_15_posts values (0), (2), (0), (6), (0), (42);
    Query OK, 6 rows affected (0.02 sec)
    Records: 6  Duplicates: 0  Warnings: 0
    
    mysql> alter table c_15_posts modify id int auto_increment primary key;
    Query OK, 6 rows affected (0.04 sec)
    Records: 6  Duplicates: 0  Warnings: 0
    
    mysql> select * from c_15_posts;
    +----+
    | id |
    +----+
    |  1 |
    |  2 |
    |  3 |
    |  6 |
    |  7 |
    | 42 |
    +----+
    

    0の行は43から始まりませんが、一意の値を受け取ります。次の挿入はID43を取得します。



    1. DBaaSフェイルオーバーソリューションと手動リカバリセットアップの比較

    2. 選択クエリを作成するための10のMicrosoftAccessのヒント

    3. SQLServerでgroup_concatを使用してクエリを実行する方法

    4. PARSENAME()を使用して、SQLServerのオブジェクト名の一部を返します