2013-12-07 5 views
2

В НИЖНЕЙ ЧАСТИ ЭТОГО ВОПРОСА ОКОНЧАТЕЛЬНЫЙ КОД, КОТОРЫЙ НАКОНЕЧНО РАБОТАЕТ!Импорт CSV-данных с использованием PHP/MySQL - синтаксис Mysqli

Пытается реализовать это (Importing CSV data using PHP/MySQL). Я, должно быть, почти там ...

notes1: мой $ sql пришел прямо из копии/вставки phpmyadmin (сгенерировал PHP-код) и отлично работал в phpmyadmin.

примечание2: если я прокомментирую строку $ sql = "DELETE FROM dbase", код работает просто отлично (и таблица очищается).

Так что, если я знаю, что мой sql прав, и мой код может запускать другие sqls, почему нижеследующее не работает ?! Im получение:

вызов функции члена выполнить() на не-объект - для линии

$stmt->execute(); 

Полный код:

<?php 
$mysqli = new mysqli('localhost','root','pass','dbase'); 
/* check connection */ 
if (mysqli_connect_errno()) { 
printf("Connect failed: %s\n", mysqli_connect_error()); 
exit(); 
} 

$sql = "LOAD DATA INFILE \'./myfile.csv\' INTO TABLE tab\n" 
. " FIELDS TERMINATED BY \',\'\n" 
. " LINES TERMINATED BY \'\\r\\n\'\n" 
. " IGNORE 1 LINES"; 

//$sql="DELETE FROM dbase"; 

$stmt=$mysqli->prepare($sql); 
$stmt->execute(); 
$stmt->close(); 
$mysqli->close(); 
?> 

ТКС заранее!

EDIT:

Сделано ниже изменений и по-прежнему не работает!

новый код:

<?php 

$mysqli = new mysqli('localhost','root','pass','dbase'); 
/* check connection */ 
if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

/* return name of current default database */ 
if ($result = $mysqli->query("SELECT DATABASE()")) { 
    $row = $result->fetch_row(); 
    printf("Default database is %s.\n", $row[0]); 
    $result->close(); 
} 

$sql = "LOAD DATA INFILE 'C:/xampp/htdocs/myfile.csv' INTO TABLE tab 
     FIELDS TERMINATED BY ',' 
    LINES TERMINATED BY '\\r\\n' 
    IGNORE 1 LINES"; 

echo "<br>"; 
echo "<br>"; 
echo $sql; 
echo "<br>"; 
echo "<br>"; 
$stmt=$mysqli->prepare($sql); 

/* Prepared statement, stage 1: prepare */ 
if (!($stmt = $mysqli->prepare($sql))) 
{ echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error; 
} 


// NOTE HERE WE'RE DUMPING OUR OBJ TO SEE THAT IT WAS 
// CREATED AND STATUS OF PREPARE AND THEN KILLING SCRIPT 
var_dump($mysqli); 
exit(); 

//$sql="DELETE FROM intrasdump 

$stmt=$mysqli->prepare($sql); 
$stmt->execute(); 
$stmt->close(); 
$mysqli->close(); 
?> 

Что я вижу в моем браузере, когда я побежал это следующее:

По умолчанию база данных имя_бд.

LOAD DATA 'C: /xampp/htdocs/myfile.csv' входной_файл в таблицу Поля вкладки TERMINATED BY '' LINES TERMINATED BY '\ г \ п' ИГНОРИРУЙТЕ 1 ЛИНИИ

Подготовьте не удалось: (1295) Эта команда не поддерживается в подготовленном протоколе whileobject (mysqli) # 1 (19) {["affected_rows"] => int (-1) ["client_info"] => string (79) "mysqlnd 5.0.11-dev - 2012-07-14 - $ Id: 40933630edef551dfaca71298a83fad8d03d62d4 $ "[" client_version "] => int (50011) [" connect_errno "] => int (0) [" connect_error "] => NULL [" errno "] => int (1295) ["error"] => string (68) "Эта команда еще не поддерживается в подготовленном протоколе оператора" ["error_list"] => array (0) {} ["field_count"] => int (1) [" host_info "] => строка (20)" localhost через TCP/IP "[" info "] => NULL [" insert_id "] => int (0) [" server_info "] => string (6)" 5 .6.11 "[" server_version "] => int (50611) [" stat "] => string (133)" Время работы: 7993 Темы: 2 Вопросы: 865 Медленные запросы: 0 Открывает: 75 Таблицы стирания: 1 Открытые таблицы: 68 Запросы в секунду avg: 0.108 "[" sqlstate "] => string (5)" 00000 "[" protocol_version "] => int (10) [" thread_id "] => int (117) [" warning_count "] => int (0)}

Примечание: Если я скопирую вставку, то строка sql, эхо-указана выше в приглашении mysql, будет работать нормально. Это должно означать, что проблема как с расположением файлов, так и с строкой sql в порядке, нет ???

как это может быть так сложно ?!

EDIT 3.

Tks для ответов на все вопросы и комментарии.Окончательный код версии ниже работы:

<?php 

$mysqli = new mysqli('localhost','root','pass','dbname'); 
/* check connection */ 
if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

$sql = "LOAD DATA INFILE 'C:/xampp/htdocs/myfile.csv' INTO TABLE tab 
     FIELDS TERMINATED BY ',' 
     LINES TERMINATED BY '\\r\\n' 
     IGNORE 1 LINES"; 

//Try to execute query (not stmt) and catch mysqli error from engine and php error 
if (!($stmt = $mysqli->query($sql))) { 
    echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error; 
}; 
?> 

полезные заметки:

  • примечание путь к файлу использует FRW-слэш вместо окон-умолчанию обратно-слэш. По порядку просто заметьте работу. Бог знает, как я понял, что один из них ...

  • использовать многие коды отладки, предлагаемые в ответах. Я думаю, один эффективный способ проверить, правильно ли ваш sql для эха (echo $sql), и скопировать/вставить в вашу подсказку sql. не доверяйте функциям phpmyadmin 'create php PHP code'.

  • иметь в виду 'Подготовленные stmts не поддерживают LOAD DATA'

+0

Я думаю, что phpmyadmin предположил, что вы должны заключить запрос в одинарные кавычки, чтобы он ускользнул от них. Просто удалите \ before all ', и я думаю, что он должен работать. Или заключите запрос в «вместо двойных кавычек» – AbraCadaver

+0

Поскольку вы используете двойные кавычки снаружи, вам не нужно избегать одиночных кавычек. И не проблема, но \ n и \ r вообще не нужны , и загромождать вашу строку.Вы можете смело удалить их – fvu

+0

И что @fvu сказал, я не смотрел на это :) – AbraCadaver

ответ

1

EDIT для Возможное решение: Подготовленные stmts не поддерживают LOAD DATA.

Если вы используете mysqli_query - вместо mysqli->prepare ..-> выполнить(); это должно сработать.

Итак:

//Connect as normal above 
$sql = "LOAD DATA INFILE '/myfile.csv' INTO TABLE tab" 
. " FIELDS TERMINATED BY ','" 
. " LINES TERMINATED BY '\r\n'" 
. " IGNORE 1 LINES"; 

//$sql="DELETE FROM dbase"; 
// $stmt = $mysqli->query($sql); 
// Integrate other posters good recc to catch errors: 

//Try to execute query (not stmt) and catch mysqli error from engine and php error 
if (!($stmt = $mysqli->query($sql))) { 
    echo "\nQuery execute failed: ERRNO: (" . $mysqli->errno . ") " . $mysqli->error; 
} 

полезно еще var_dump ($ MySQLi) здесь, чтобы увидеть результат я получил доступ запрещен, как в моем окр мы запретить загрузку файла, но это говорит мне, двигатель успешно анализироваться и попытался выполнить запрос.

Вы должны получить лучшую информацию об ошибке, есть немного, что может идти дальше, вот как я бы закопать:

Диагностика процесса, чтобы добраться до этой точки:

$sql = "LOAD DATA INFILE ..."; 
echo $sql; 
$stmt=$mysqli->prepare($sql); 

// NOTE HERE WE'RE DUMPING OUR OBJ TO SEE THAT IT WAS 
// CREATED AND STATUS OF PREPARE AND THEN KILLING SCRIPT 
var_dump($mysqli); 
exit(); 

Результаты на моей коробке (не самое лучшее представление):

object(mysqli)#1 (18) { 
    ... 
    string(68) "This command is not supported in the 
       prepared statement protocol yet" 

2. Другие возможные ошибки вы видите

Недостаточные privs FILE или Ненадлежащее Справочник файла Loc

PhpMyAdmin является довольно изолированном и будет работать совершенно иначе, чем Mysqli/PHP.

Обратите внимание на следующее из документации MySQL и прочтите этот раздел. Как я уже сказал, LOAD..FILE - очень чувствительная операция с множеством ограничений. LOAD...FILEMySQL Docs

По соображениям безопасности, при чтении текстовых файлов, расположенных на сервере, файлы должны либо находиться в каталоге баз данных или быть читаемым все. Кроме того, чтобы использовать LOAD DATA INFILE для файлов сервера, вы должны иметь привилегию FILE. См. Раздел 6.2.1 «Привилегии, предоставляемые MySQL». Для операций загрузки, отличных от LOCAL, если системная переменная secure_file_priv установлена ​​на непустое имя каталога, загружаемый файл должен быть , находящимся в этом каталоге.

+1

Я следил за каждым шагом вашего ответа. Я действительно получаю ту же ошибку, которую я прочитал в вашем поле = «Эта команда еще не поддерживается в подготовленном протоколе выполнения». Pls взглянуть на мои правки! –

+0

@ Амариани Я заглянул в это. См. Мой отредактированный ответ выше для возможного решения. – cerd

+0

Бинго! Работаю как шарм! Интересно, как вы поняли, что «Подготовленные stmts не поддерживают LOAD DATA».Должен ли я опубликовать свое окончательное решение в качестве редактирования в моем вопросе для других жертв LOAD DATA? Я немного новичок в этой вещи стека. tks a zillion в любом случае! –

2

Вы, вероятно, следует ставить охрану, чтобы определить, когда готовят вызов не удается:

/* Prepared statement, stage 1: prepare */ 
if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) { 
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error; 
} 

Источник: http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php

Я также проверил бы путь для команды LOAD DATA INFILE. Phpmyadmin может устанавливать другую переменную пути. Если вы попытаетесь временно установить абсолютный путь unix (и убедитесь, что mysql имеет соответствующее разрешение для этого каталога), это может устранить проблему.

Однако в любом случае вы должны вывести ошибку из клиента mysql, чтобы дать вам лучшее представление о том, что вызывает проблему.

Наконец, я попытаюсь выполнить команду непосредственно в клиенте командной строки MySQL. Если в phpmysql или в mysqli php-клиенте происходит какое-либо «волшебство», оно будет отображаться с помощью клиента mysql cli, так как два из клиентов будут успешны, если вы потерпите неудачу (по сравнению с вашими предположениями).

Раньше я сталкивался с подобной проблемой, и в итоге это был странный способ выхода из разделителя MySQL, поэтому я бы посмотрел, что вы правильно выполнили параметры TERMINATED BY.

+0

Я последовал за тобой шаг за шагом, и я до сих пор не знаю Homer6. Пожалуйста, взгляните на мое редактирование. –

+1

Первым шагом, который я предложил, было вывести сообщение об ошибке. , как выясняется, именно в чем проблема: «Эта команда i s не поддерживается в подготовленном протоколе yetobject (mysqli) # 1 «Рад, что вы нашли свою проблему. – Homer6

+0

@ Homer6 хороший вызов по вышеуказанному коду, я добавил его в ответ выше, как средство, чтобы проиллюстрировать проблему вместе с работой. – cerd

0

Что говорится Homer6, и, вероятно:

$sql = "LOAD DATA INFILE './myfile.csv' INTO TABLE tab" 
. " FIELDS TERMINATED BY ','" 
. " LINES TERMINATED BY '\\r\\n'" 
. " IGNORE 1 LINES"; 

Может нужно проверить путь к файлу, а также. Я не знаю, что такое ./ относительно запроса. Возможно, не расположение файлов PHP.

+0

Это я пробовал все возможные комбинации исправления строки! –

+0

У меня были большие проблемы с использованием подготовки с LOAD DATA, но в действительности ваша строковая строка выше той, которая работает! –

Смежные вопросы