TL;DR
Fel #1064 betyder att MySQL inte kan förstå ditt kommando. Så här fixar du det:
Läs felmeddelandet. Den talar om för dig exakt var i ditt kommando MySQL blev förvirrad.
Undersök ditt kommando. Om du använder ett programmeringsspråk för att skapa ditt kommando, använd
echo
,console.log()
, eller motsvarande för att visa hela kommandot så att du kan se det.Kontrollera manualen. Genom att jämföra med vad MySQL förväntade sig vid den tidpunkten , problemet är ofta uppenbart.
Sök efter reserverade ord. Om felet inträffade på en objektidentifierare, kontrollera att det inte är ett reserverat ord (och, om det är det, se till att det är korrekt citerat).
-
Aaaagh!! Vad betyder #1064 betyder ?
Felmeddelanden kan se ut som gobbledygook, men de är (ofta) otroligt informativa och ger tillräckliga detaljer för att fastställa vad som gick fel. Genom att förstå exakt vad MySQL säger till dig kan du beväpna dig för att åtgärda eventuella problem av detta slag i framtiden.
Som i många program är MySQL-fel kodade enligt typ problem som uppstod. Fel #1064 är ett syntaxfel.
-
Vad är denna "syntax" som du talar om? Är det trolldom?
Medan "syntax" är ett ord som många programmerare bara stöter på i datorsammanhang, är det i själva verket lånat från en bredare lingvistik. Det hänvisar till meningsstruktur:d.v.s. grammatikens regler; eller, med andra ord, reglerna som definierar vad som utgör en giltig mening inom språket.
Till exempel innehåller följande engelska mening ett syntaxfel (eftersom den obestämda artikeln "a" alltid måste föregå ett substantiv):
Denna mening innehåller syntaxfel a.
-
Vad har det med MySQL att göra?
Närhelst man utfärdar ett kommando till en dator, är en av de allra första sakerna som den måste göra att "tolka" det kommandot för att förstå det. Ett "syntaxfel" betyder att analysatorn inte kan förstå vad som efterfrågas eftersom det inte utgör ett giltigt kommando inom språket:med andra ord, kommandot bryter mot programmeringsspråkets grammatik .
Det är viktigt att notera att datorn måste förstå kommandot innan den kan göra något med det. Eftersom det finns ett syntaxfel har MySQL ingen aning om vad man är ute efter och ger därför upp innan den ens tittar på databasen och därför är schemat eller tabellinnehållet inte relevant.
-
-
Hur fixar jag det?
Uppenbarligen måste man avgöra hur det kommer sig att kommandot bryter mot MySQL:s grammatik. Detta kan låta ganska ogenomträngligt, men MySQL försöker verkligen hjälpa oss här. Allt vi behöver göra är...
-
Läs meddelandet!
MySQL berättar inte bara för oss exakt där parsern stötte på syntaxfelet, men ger också ett förslag för att fixa det. Tänk till exempel på följande SQL-kommando:
UPDATE my_table WHERE id=101 SET name='foo'
Det kommandot ger följande felmeddelande:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE id=101 SET name='foo'' at line 1
MySQL berättar för oss att allt verkade bra upp till ordet
WHERE
, men sedan uppstod ett problem. Med andra ord, den förväntade sig inte att stöta påWHERE
vid den tidpunkten.Meddelanden som säger
...near '' at line...
betyder helt enkelt att slutet av kommandot påträffades oväntat:det vill säga något annat bör visas innan kommandot slutar. -
Undersök den faktiska texten i ditt kommando!
Programmerare skapar ofta SQL-kommandon med hjälp av ett programmeringsspråk. Till exempel kan ett php-program ha en (fel) rad så här:
$result = $mysqli->query("UPDATE " . $tablename ."SET name='foo' WHERE id=101");
Om du skriver detta på två rader
$query = "UPDATE " . $tablename ."SET name='foo' WHERE id=101" $result = $mysqli->query($query);
sedan kan du lägga till
echo $query;
ellervar_dump($query)
för att se att frågan faktiskt sägerUPDATE userSET name='foo' WHERE id=101
Ofta ser du ditt fel omedelbart och kan åtgärda det.
-
Lyd order!
MySQL rekommenderar också att vi "kollar manualen som motsvarar vår MySQL-version för rätt syntax att använda ". Låt oss göra det.
Jag använder MySQL v5.6, så jag vänder mig till den versionens manuella inmatning för en
UPDATE
kommando . Det allra första på sidan är kommandots grammatik (detta är sant för varje kommando):UPDATE [LOW_PRIORITY] [IGNORE] table_reference SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]
Handboken förklarar hur man tolkar denna syntax under typografiska och syntaxkonventioner , men för våra ändamål räcker det att erkänna att:satser inom hakparenteser
[
och]
är valfria; vertikala streck|
ange alternativ; och ellipser...
beteckna antingen ett utelämnande för korthets skull, eller att föregående sats kan upprepas.Vi vet redan att analysatorn trodde att allt i vårt kommando var okej innan
WHERE
nyckelord, eller med andra ord fram till och med tabellreferensen. När vi tittar på grammatiken ser vi atttable_reference
måste följas avSET
nyckelord:medan det i vårt kommando faktiskt följdes avWHERE
nyckelord. Detta förklarar varför parsern rapporterar att ett problem uppstod vid den tidpunkten.
En reservationskommentar
Naturligtvis var detta ett enkelt exempel. Men genom att följa de två stegen som beskrivs ovan (dvs. observera exakt var i kommandot parsern fann att grammatiken kränktes och jämförde med manualens beskrivning av vad som förväntades vid den tidpunkten ), så gott som alla syntaxfel kan lätt identifieras.
Jag säger "nästan alla", eftersom det finns en liten klass av problem som inte är så lätta att upptäcka – och det är där parsern tror att språkelementet som påträffas betyder en sak medan du avser att det ska betyda en annan. Ta följande exempel:
UPDATE my_table SET where='foo'
Återigen, parsern förväntar sig inte att stöta på
WHERE
vid denna tidpunkt och så kommer att uppstå ett liknande syntaxfel—men du hade inte tänkt dig detwhere
att vara ett SQL-nyckelord:du hade tänkt att det skulle identifiera en kolumn för uppdatering! Men som dokumenterats under schemaobjektnamn :Om en identifierare innehåller specialtecken eller är ett reserverat ord, måste du citera det när du refererar till det. (Undantag:Ett reserverat ord som följer en punkt i ett kvalificerat namn måste vara en identifierare, så det behöver inte citeras.) Reserverade ord listas på Avsnitt 9.3, "Sökord och reserverade ord" .
[ deletia ]
Identifieringscitattecknet är backtick ("
`
”):mysql> SELECT * FROM `select` WHERE `select`.id > 100;
Om
ANSI_QUOTES
SQL-läget är aktiverat, det är också tillåtet att citera identifierare inom dubbla citattecken:mysql> CREATE TABLE "test" (col INT); ERROR 1064: You have an error in your SQL syntax... mysql> SET sql_mode='ANSI_QUOTES'; mysql> CREATE TABLE "test" (col INT); Query OK, 0 rows affected (0.00 sec)
-