Большой Воронежский Форум
» Программирование>txt->mysql обработка полей
pegas1981 10:14 21.04.2005
есть текстовый файл с полями следующего вида:

труба|1/2"; 3/4"|12|50.00

Вопрос! Как прописать FIELDS, чтобы обрабатывалось поля такого вида, вот такая функа чего-то не пашет:

function list_file($file_db, $usertable)
{
$path=$_SERVER['DOCUMENT_ROOT'].$file_db;
$result=mysql_query("LOAD DATA INFILE '$path'
INTO TABLE $usertable
FIELDS TERMINATED BY '|'
OPTIONALLY ENCLOSED BY '"'
ESCAPED BY '\\'
LINES TERMINATED BY '\n'
(text1, text2, text3, text4);");
}

ЗЫ. Если бы не эти дюймы, то такая функа работала бы:
function list_file($file_db, $usertable)
{
$path=$_SERVER['DOCUMENT_ROOT'].$file_db;
$result=mysql_query("LOAD DATA INFILE '$path'
INTO TABLE $usertable
FIELDS TERMINATED BY '|'
OPTIONALLY ENCLOSED BY ''
LINES TERMINATED BY '\n'
(text1, text2, text3, text4);");
}

Заранее благодарен за помощь. [Ответ]
mikе 11:01 21.04.2005
можно читать файл, разбивать ручками в массив,
а потом уже писать в базу. я бы так делал. [Ответ]
pegas1981 11:10 21.04.2005
это удобно когда файл всего из пары - тройки сотен строк, а если их несколько тысяч? нагруз на сервак всетаки приличный.... [Ответ]
mikе 11:24 21.04.2005
pegas1981, так тебе это что, по сотне раз в сутки делать?
Раз перегнал - би хэппи [Ответ]
Николай Калгин 11:33 21.04.2005
дык читай файл не fopen а file... т.е. целиком.
у меня файл на 20 мегов парсится(regex) и перегоняется в базу меньше чем за минуту. [Ответ]
pegas1981 11:45 21.04.2005
это как вариант хорошо... но всетаки если ответ с использованием моего варианта? [Ответ]
ilyaerin 02:49 22.04.2005
pegas1981 прочитай файл на localhost-е, переконвертируй в удобный тебе формат, а потом и заливай на сервер => mysql. [Ответ]
pegas1981 13:14 22.04.2005
Вопрос снинимается, т.к. хост все равно не дает привелегию FILE на запись фунцией LOAD DATA в базу mysql. Решаю методом INSERT INTO ... [Ответ]
pegas1981 14:03 22.04.2005
Тему открываю, но теперь другой вопрос:
надо придумать как создать дополнительно два поля: id и par_id для рекурсивного вывода, а то голову уже поломал...

есть файл следующего вида (количество полей может изменяться):

id|par_id|номер товара|уровень|наименование|наличие|цена1|цена2
1|1|100|1|МЕТАЛЛ
2|1|100000|2|ТРУБА
3|2|100100|3|труба 1/2"|1|30.00|25.00
4|2|100200|3|труба 3/4"|0|18.00|15.00
5|2|200000|2|ЛИСТ
6|5|200100|3|лист|1|32.00|5.00

Вот работающая функа, тока без создания двух доп. полей id и par_id

function loadFile($usertable, $dbname, $file_db)
{
$file=file($_SERVER['DOCUMENT_ROOT'].$file_db);
$col=count($file);
$id=1;
while (list($k, $v)=each($file))
{
$line=explode('|', $v);
$m=0;
foreach($line as $key=>$value)
{
switch ($key)
{
case 0: $colName[$key]='idprod';
break;
case 1: $colName[$key]='level';
break;
case 2: $colName[$key]='text1';
break;
case 3: $colName[$key]='text2';
break;
case 4: $colName[$key]='text3';
break;
case 5: $colName[$key]='text4';
break;
}
if ($m==0)
{
$query=mysql_query("INSERT IGNORE INTO $usertable (id, ".$colName[$key].") VALUES ('".$id++."', '".$value."');");
$m=1;
}
else
$query=mysql_query("UPDATE IGNORE ".$usertable." SET id='".$id."', ".$colName[$key]."='".$value."';");
}
}
}
[Ответ]
pegas1981 16:09 22.04.2005
короче был файлец такого вида:
уровень|номер товара|наименование|наличие|цена1|цена2
1|100|МЕТАЛЛ
2|100000|АРМАТУРА
3|100100|Арматура 6 мм|1|23844.00|19870.00
3|100200|Арматура 8 мм|1|23064.00|19220.00
3|100300|Арматура 10 мм|1|21300.00|17750.00
2|200000|БАЛКА
3|200100|Балка №10|0|10800.00|9000.00
3|200200|Балка №12|1|22860.00|19050.00
3|200300|Балка №12 Б1|1|22500.00|18750.00

а надо было сделать такого:
id|par_id|уровень|номер товара|наименование|наличие|цена1|цена2
1|1|1|100|МЕТАЛЛ
2|1|2|100000|АРМАТУРА
3|2|3|100100|Арматура 6 мм|1|23844.00|19870.00
4|2|3|100200|Арматура 8 мм|1|23064.00|19220.00
5|2|3|100300|Арматура 10 мм|1|21300.00|17750.00
6|1|2|200000|БАЛКА
7|6|3|200100|Балка №10|0|10800.00|9000.00
8|6|3|200200|Балка №12|1|22860.00|19050.00
9|6|3|200300|Балка №12 Б1|1|22500.00|18750.00

т.е. добавить 2 столбца с идентификаторами уровня вложенности, по которым в дальнейшем при рекусивной выборке из базы будут браться данные.

вопрос решил самостоятельно... кому интересно вот код... правда он получился так сказать не очень удобоваримым... может кто посоветует как упростить?

[PHP]
function loadFile($usertable, $dbname, $file_db)
{
$file=file($_SERVER['DOCUMENT_ROOT'].$file_db);
$col=count($file);
$id=0;
$idp=array(0=>0, 1=>0);
$level=1;
$levelNew=1;
$idpar=0;
while (list($k, $v)=each($file))
{
$line=explode('|', $v);
$m=0;
foreach($line as $key=>$value)
{
switch ($key)
{
case 0: $colName[$key]='level';
break;
case 1: $colName[$key]='idprod';
break;
case 2: $colName[$key]='text1';
break;
case 3: $colName[$key]='text2';
break;
case 4: $colName[$key]='text3';
break;
case 5: $colName[$key]='text4';
break;
}
if ($m==0)
$id++;
if ($colName[$key]=='level')
$levelNew=$value;
if ($level<$levelNew)
{
$level=$levelNew;
if ($id>1)
{
$idp[$levelNew]=$id-1;
$idpar=$idp[$levelNew];
}
else
{
$idp[$levelNew]=$id;
$idpar=$idp[$levelNew];
}
}
if ($level>=$levelNew)
{
$level=$levelNew;
if ($idp[$levelNew]==0)
$idp[$levelNew]=1;
$idpar=$idp[$levelNew];
}
if ($m==0)
{
$query=mysql_query("INSERT IGNORE INTO $usertable (id, idp, ".$colName[$key].") VALUES ('".$id."', '".$idpar."', '".$value."');");
$m=1;
}
else
$query=mysql_query("UPDATE IGNORE ".$usertable." SET id='".$id."', id='".$idpar."', ".$colName[$key]."='".$value."';");
}
}
}
}
[/PHP]

Всем огромное спасибо за участие и помощь. :idolater: [Ответ]
ilyaerin 12:31 26.04.2005
Сережа, вот код функции, которая рекурсивно собирает все данные из таблицы базы и возвращает их в виде удобного массива, где 0-элемент данные о самом разделе.

Сообщение от :
// Извлекаем из таблицы.
function get_data( $level = 0, $tbl_name = "" )
{
$res = mysql_query( "select * from ".$tbl_name." where pid=".$level." ;" );
if( 0 == mysql_num_rows($res) )
return -1;
else
{
$i = 1;
while( $data = mysql_fetch_array( $res, MYSQL_ASSOC ) )
if( -1 != ( $tmp = get_data($data["id"], $tbl_name) ) )
{
$tmp[0] = $data;
ksort( $tmp );
$out[$i++] = $tmp;
}
else
$out[$i++] = $data;

return $out;
}
}

// Ф-ция, которая выводит этот массив в более-менне читабельном виде.
function echo_data( $out )
{
foreach( $out as $k => $v )
if( isset($v[0]) )
{
echo "<b>".$v[0]["id"]." - ".$v[0]["pid"]."</b>: ".$v[0]["name"]." <i>".$v[0]["cost"]."</i><br>";
echo "<div style='margin-left: 30px'>";
unset( $v[0] );
echo_data( $v );
echo "</div>";
}
else
echo "<b>".$v["id"]." - ".$v["pid"]."</b>: ".$v["name"]." <i>".$v["cost"]."</i><br>";
}

// Пример использования
echo_data( get_data() );

[Ответ]
pegas1981 13:19 27.04.2005
спасиб илья! :idolater:
есть конечно пара вопросов по постороению, но я их может потом задам. [Ответ]
Вверх