Запрос вставки строки в таблицу с условием наличия файла в директории

Тема в разделе "Базы данных", создана пользователем 1van, 22 мар 2018.

Модераторы: latteo
  1. 1van

    1van Постоялец

    Регистр.:
    22 май 2013
    Сообщения:
    98
    Симпатии:
    18
    Написал запрос, который вставляет в таблицу БД запись об изображении из результатов парсинга:
    Код:
    INSERT INTO kajio_djcf_images (item_id,type,name,ext,path,caption,ordering,optimized) VALUES ('%Номер объявления%','item','%Номер объявления%'"_1",'jpg','/components/com_djclassifieds/images/item/','%Краткое описание%','2','0');
    Как сделать, средством MySQL запроса, так, чтобы запись вставлялась только, если файл %Номер объявления%'"_1",'jpg' (123456789.jpg) существует в определённой директории (например C:/images)?
     
    Последнее редактирование: 22 мар 2018
  2. deedjey

    deedjey Постоялец

    Регистр.:
    20 янв 2014
    Сообщения:
    73
    Симпатии:
    45
    bool file_exists ( string $filename ) проверяет наличие файла по заданному пути. Результат булевый (True или False)
    Пример:
    Код:
    <?php
    $filename = '/path/to/foo.txt';
    
    if (file_exists($filename)) {
        echo "Файл $filename существует";
    } else {
        echo "Файл $filename не существует";
    }
    ?>
    
     
  3. 1van

    1van Постоялец

    Регистр.:
    22 май 2013
    Сообщения:
    98
    Симпатии:
    18
    Нужно сделать средством MySQL запроса. Не уточнил в теме, сейчас исправлю.
    Может что-то с WHERE?
     
  4. deedjey

    deedjey Постоялец

    Регистр.:
    20 янв 2014
    Сообщения:
    73
    Симпатии:
    45
    Можно использовать LOAD_FILE(), но тут важно помнить о безопасности, не рекомендуется давать учётной записи, под которой работает MySQL, права на файловую систему выше минимально необходимого.
     
    pautina нравится это.
  5. 1van

    1van Постоялец

    Регистр.:
    22 май 2013
    Сообщения:
    98
    Симпатии:
    18
    Насколько я понимаю
    Мне не нужно содержимое файла.
    Есть директория C:/images. В ней файлы картинок вида 123456789.jpg, 123456789_1.jpg, 123456789_2.jpg ... , где 123456789 номер объявления к которому они относятся. Запрос (из шапки), вставляет в таблицу информацию о файле. Картинок к каждому объявлению может быть от 0 до 20.
    Вопрос: Как в запросе проверить наличие файла с именем 123456789_n.jpg и, если такого файла нет в указаной директории, запись в таблицу НЕ ДЕЛАТЬ?
     
  6. deedjey

    deedjey Постоялец

    Регистр.:
    20 янв 2014
    Сообщения:
    73
    Симпатии:
    45
    Не очень глубоко знаю Mysql, но возможно сработает такой запрос
    Код:
    SELECT id, path, ISNULL(LOAD_FILE(path)) as not_exists
    FROM images
    HAVING not_exists = 1
    
    Функция LOAD_FILE пытается загрузить файл в виде строки и возвращается, NULL когда он терпит неудачу.
    Cбой в этом случае может быть связан с тем, что mysql просто не может прочитать это конкретное местоположение, даже если файл действительно существует/
    Это не стандартный SQL, хотя MySQL позволяет делать так. Чтобы следовать стандартам это должно выглядеть так:
    Код:
    SELECT *
    FROM images
    WHERE LOAD_FILE(PATH) IS NULL
    
    Статейка на тему обхода ограничений на чтение файлов в Mysql, может будет вам полезна
     
    1van нравится это.
  7. Black Hat

    Black Hat

    Регистр.:
    15 май 2015
    Сообщения:
    163
    Симпатии:
    104
    Не учите плохому. Да, задачу это решает. Но если этот способ включать в свою обычную практику - он ужасен.
    1. безопасность
    2. надежность: файл есть, но мускул его не смог прочитать
    3. переносимость: перенесли свое решение на Linux сервер, а там C:/images нет ...
    4. скорость работы: на ста файлах вы не почувствуете, на ста тысячах - да
    5. масштабируемость: что если файлы и БД на разных серверах
    6. непрофессиональность: не показываете такой код своему работодателю. не оценит
     
    pautina и Nei нравится это.
  8. 1van

    1van Постоялец

    Регистр.:
    22 май 2013
    Сообщения:
    98
    Симпатии:
    18
    Так и есть ))
    Пробую реализовать другой подход. Создал таблицу f_nanme, в которую при помощи php скрипта заношу все файлы из директории.
    Теперь нужен MySQL скрипт, который сравнивает таблицу kajio_djcf_images с f_nanme и если в kajio_djcf имя файла присутствует, а в f_nanme нет - удаляет эту строку.
     
  9. Nei

    Nei Nosce te ipsum

    Регистр.:
    5 сен 2009
    Сообщения:
    663
    Симпатии:
    524
    Не проще ли как-то так сделать:
    PHP:
    if (is_file($filename)) {
        
    $q='mysql_query here';
        
    mysql_query ($q) or die (mysql_error);
    }
     
    Black Hat нравится это.
  10. 1van

    1van Постоялец

    Регистр.:
    22 май 2013
    Сообщения:
    98
    Симпатии:
    18
    Вот php запрос, который смотрит в директорию item и записывает наименования файлов в таблицу images_fn БД:
    PHP:
        mysqli_report(MYSQLI_REPORT_ERROR MYSQLI_REPORT_STRICT);
        
    $db=mysqli_connect($db_server,$db_user,$db_password,$db_name);
        
    $dirimg="/home/item/";
        
    $a=array();
        if (
    is_dir($dirimg)){
            if (
    $ukdirimg opendir($dirimg)){
                while ((
    $file=readdir($ukdirimg))!==false){
                    
    $kandidat='/home/item/'.$file;
                    if (
    is_file($kandidat)){
                        
    array_push($a$file);
                    }
                }
            
    closedir($ukdirimg);
            }
        }
    $kol=count($a);
        foreach (
    $a as $i => $filename){
            
    $query4="SELECT count(*) as CCC FROM `$db_name`.`images_fn` where (`file_name`='".$filename."')";
            
    $result4=mysqli_query($db,$query4);
            
    $date5=mysqli_fetch_assoc($result4);
            if (
    $date5["CCC"] == 0){
                
    $query="INSERT INTO `$db_name`.`images_fn` (`id`, `file_name`) VALUES (NULL, '".$filename."')";
                
    $result=mysqli_query($db,$query);
            }
        }

        
    $query3="SELECT * FROM `$db_name`.`images_fn`";
        
    $result3=mysqli_query($db,$query3);
    $f=1;
        
    mysqli_close($db);
    Скрипт запускаю через shell. Работает, конечно долго (в папке более 500 тыс. файлов), но свои функции выполняет.

    Подскажите, как сделать так, чтобы в таблицу заносились наименования файлов без расширения (в моём случае все расширения .jpg)
    И второй вопрос: В сканируемой папке есть подпапки. Как заставить скрипт сканировать их тоже?
     
    Последнее редактирование: 16 май 2018