我们走了:
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
WTF?
修改
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 ......
答案 0 :(得分: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
);
答案 1 :(得分:1)
可能你有autocommit = 1并在提交后释放表。
尝试:
SET AUTOCOMMIT = 0
开始交易之前。
http://dev.mysql.com/doc/refman/5.0/es/innodb-and-autocommit.html
答案 2 :(得分:0)
您正在锁定WRITE
的表格。您需要锁定READ
的表,因为您正在使用只从表中读取的SELECT
。
但是你不应该真正锁定表,因为这会阻止并发。
修改强>
您还需要使用别名,因为在查询中使用同一个表两次。
即
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
);