2012-10-17 21 views
6

jedziemy:Błąd blokady mysql lub błąd?

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?

EDIT

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: Kwerenda działa dobrze, jeśli nie zablokować tabeli. pd: To jest tylko przykładowe uproszczenie pytania .. w prawdziwym życiu jest DELETE ...

+1

sprawdzić moją odpowiedź. musisz podać alias do wszystkich tabel. i trzeba również zablokować tabelę podzapytania za pomocą tego aliasu –

Odpowiedz

12

podczas korzystania z tabel blokady, trzeba zablokować wszystkie tabele w zapytaniu. Podczas korzystania z podzapytania tworzy on tabelę. i nie blokujesz go. z tego powodu otrzymujesz błąd.

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

dać aliasu do tabeli wewnętrznej

badaną próbkę:

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) 
) 

I chyba trzeba to:

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 
); 
0

Jesteś tabel blokowania dla WRITE. Musisz zablokować tabele dla READ, ponieważ używasz SELECT, który właśnie czyta z tabel.

Nie należy jednak blokować tabel, ponieważ zapobiega to współbieżności.

EDIT

też trzeba używać aliasów jak używasz tej samej tabeli dwukrotnie w zapytaniu.

tj

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 
    ); 
Powiązane problemy