6

さあ行こう:

mysql> LOCK TABLES radcheck WRITE;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM radcheck WHERE id NOT IN (
    ->     SELECT id FROM (
    ->         SELECT id FROM radcheck  WHERE attribute = 'Password' GROUP BY UserName HAVING COUNT(*) > 1
    ->      ) AS c
    -> );
ERROR 1100 (HY000): Table 'radcheck' was not locked with LOCK TABLES

なんてこと?

編集

SET AUTOCOMMIT = 0
    -> ;
Query OK, 0 rows affected (0.00 sec)

mysql> LOCK TABLES radcheck WRITE;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM radcheck WHERE id NOT IN ( SELECT id FROM radcheck  WHERE attribute = 'Password' GROUP BY UserName HAVING COUNT(*) > 1 );
ERROR 1100 (HY000): Table 'radcheck' was not locked with LOCK TABLES



mysql> LOCK TABLES radcheck READ;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM radcheck WHERE id NOT IN ( SELECT id FROM radcheck  WHERE attribute = 'Password' GROUP BY UserName HAVING COUNT(*) > 1 );
ERROR 1100 (HY000): Table 'radcheck' was not locked with LOCK TABLES

pd: テーブルをロックしないと、クエリは正常に機能します。pd:これは質問を単純化するための単なる例です..実際にはDELETEです...

4

3 に答える 3

12

ロックテーブルを使用する場合は、クエリ内のすべてのテーブルをロックする必要があります。サブクエリを使用すると、テーブルが作成されます。そして、あなたはそれをロックしていません。そのため、エラーが発生します。

参照: http ://dev.mysql.com/doc/refman/5.0/en/lock-tables.html

内部テーブルにエイリアスを与える

テストされたサンプル:

lock tables products as p1 write, products as p2 write ;
select product_id  from products as p1
where product_id  not in ( 
select product_id from products p2 where product_id in (1,2)
) 

そしておそらくあなたはこれをする必要があります:

lock tables radcheck as r1 write, radcheck as r2 write ;

 SELECT * FROM radcheck r1 WHERE id NOT IN (
SELECT id FROM (
  SELECT id FROM radcheck r2 WHERE attribute = 'Password' GROUP BY UserName HAVING COUNT(*) > 1) AS c
 );
于 2012-10-17T20:50:11.743 に答える
1

おそらく autocommit = 1 で、コミット後にテーブルを解放します。

試してみてください:

SET AUTOCOMMIT = 0

取引を開始する前に。

http://dev.mysql.com/doc/refman/5.0/es/innodb-and-autocommit.html

于 2012-10-17T20:42:00.773 に答える
0

のテーブルをロックしていWRITEます。テーブルから読み取るだけREADを使用しているため、テーブルをロックする必要があります。SELECT

ただし、同時実行が妨げられるため、テーブルを実際にロックするべきではありません。

編集

クエリで同じテーブルを 2 回使用しているため、エイリアスも使用する必要があります。

すなわち

LOCK TABLES radcheck AS read1 READ, radcheck AS read2 READ;
SELECT * 
FROM radcheck AS read1
WHERE id NOT IN
   (
       SELECT id FROM radcheck AS read2
       WHERE attribute = 'Password'
       GROUP BY UserName
       HAVING COUNT(*) > 1
   );
于 2012-10-17T20:45:39.013 に答える