Ответы пользователя по тегу SQL
  • Как правильно задать запрос UPDATE где название столбца переменная?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Этот вопрос - прекрасная иллюстрация того факта, что нормализация базы данных - это не блажь оторванных от жизни теоретиков, а насущная необходимость. И её отсутствие приводит к проблемам на ровном месте.

    Уже по наличию нумерованных столбцов сразу видно, что структура БД кривая. А текущая проблема делает это еще более наглядным: собственно, сама постановка вопроса, "как задать имя столбца через переменную", говорит о том, что имя колонки используется в условии. То есть оно должно быть значением в строке.

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

    UPDATE link_count SET count=count+? WHERE link_id=? and number=?
    Ответ написан
    3 комментария
  • После регистрации пользователь в базу таблицы users не попадает..В чем проблема?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Как правильно написал Антон, пора знакомиться с таким понятием, как отладка.
    Но дополним его ответ более практическими рекомендациями.

    Во-первых, при создании соединения с БД, надо сказать ПДО, чтобы он сообщал об ошибках.
    $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    Во-вторых, временно, на период разработки, включить отображение ошибок РНР. Чтобы тупо увидеть, если произошла какая-то ошибка.
    ini_set('display_errors', 1);

    И в-третьих, начать собственно отладку.
    Для начала убедившись, что РНР код в принципе запускается, и проблема в нем, а не в форме.
    Для этого в самом начале action.php пишем большими буквами
    die("пхп хотя бы запустился");
    И если после нажатия на кнопку мы этот текст не увидели, то начинаем тупить в свою форму - а с чего она вообще должна что-то посылать в файл action.php (и попутно задаваться вопросом - а какое отношение наш вопрос имеет к php и sql?)?
    Если форма отправляется аяксом, то смотрим ответ пхп в инструментах разработчика, вкладка Сеть.

    Если обработку формы мы начали, то заезжаем внутрь условия
    die("начали обработку формы");

    И так далее, отслеживаем работу своего кода, выполняется ли он вообще, и содержат ли переменные нужные значения.

    А в целом, конечно, код очень жестокий.
    Вот прямо хочется спросить -
    зачем здесь функция test_input?
    зачем здесь try {}catch (){echo 'Error : '.$e-getMessage();}?
    зачем class Auth extends Database?
    почему showMessage - это часть класса Database? Ну вот серьёзно, каким местом вывод сообщения в браузер в виде HTML хоть как-то относится к работе с базой данных?

    Чтобы сделать этот код минимально осмысленным, надо
    выкинуть класс Database
    в класс Auth добавить
    public function __construct($pdo){
                $this->conn = $pdo;
        }

    и выкинуть из него require_once 'config.php';

    В config.php оставить только соединение с PDO
    в action написать
    require 'config.php';
    $user = new Auth($pdo);

    и выкинуть условие при регистрации, оставив только
    $user->register($name,$email,$hpass);
    $_SESSION['user'] = $email;

    И тогда этот код станет минимально осмысленным
    Ответ написан
    Комментировать
  • Какую структуру таблиц выбрать для описания некоторой сущности, у представителей которой часть атрибутов совпадает, а часть - различна?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Как правильно написали выше, общепринятой практики нет.
    С натяжкой общепринятой можно назвать практику, когда часть свойств пишется в JSON поле, но как раз для описанного в вопросе случая она не должна применяться. Здесь однозначно подходит стандартная реляционная структура. Нет гарантии? Пишем null. Нет пробега? Пишем 0 км.

    А вот если нам надо хранить совсем различные товары, например автомобили и автомагнитолы, то специфические для товара характеристики можно писать в JSON поле. Но в этом случае потребуется отдельная база данных, которая будет хранить все возможные варианты ключей в этом JSON поле.
    Ответ написан
    2 комментария
  • Как составить запрос sql?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Это надо делать не в SQL.
    Ответ написан
  • Разделение ответственности или производительность?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Мне кажется, что все прочитали только заголовок, а на текст поста никто не обратил внимания. Как обычно
    А там-то и лоснится самый ЖЫР:

    Но в этом случае мне придется выполнить 2 запроса к базе данных

    То есть вся "проблема" тут из-за каши в голове клиента, который откуда-то взял, что во втором варианте у него будет не два запроса, а один. Ну то есть понятно откуда - очередной разрабончик баз данных, который SQL видел только в кино, а база данных для него - это вот это вот prisma create.

    И только из-за этих нелепых страхов он ломает всю логику и сервис юзеров у него начинает лазить в БД постов. Что и является здесь проблемой. А не какие-то, опять же, дурацкие страхи про дублирование вызова нотификации.
    Ответ написан
    6 комментариев
  • Как сделать категории в интернет магазине?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Да в том-то и дело, что нет такого "тру решения". Даже в той же статье, из которой вы выбрали самый неудачный вариант, приведено ЧЕТЫРЕ варианта работы с деревьями.
    Высоколобые интеллектуалы считают, что тру вариант - это вложенные множества.
    Люди попроще используют материализованный путь. Из него по разделителю вырезается корневая категория телефонов, и дальше одним запросом с LIKE выбираются все дети.

    В вашем же случае самый тупой вариант - это два цикла в приложении, которое работает с БД:
    Сначала циклом пройти от телефонов верх, получая родителя, пока он не вернет пустоту. это будет корневая категория
    А потом в цикле пройти вниз, получая всех детей, и добавляя их в WHERE IN, пока запрос не вернет то же количество записей, что и предыдущий - то есть, мы дошли до дна. И подставить полученный список в таблицу товаров.

    Как вариант, приложение на старте кэширует все дерево категорий в массив, и дальше использует его для всех задач.

    А если вам нужен прямо CTE запрос, то во-первых, ставьте нормальные теги, во-вторых, приведите нормальные дампы таблиц (а не вот это на пальцах "ну есть телефончики..."), и тегайте Akina и Slava Rozhnev
    Ответ написан
  • Как выбирать сценарий при вставке данных в таблицу?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    null - это и есть "отсутствие данных".
    Надо не маяться дурью, а просто вставлять данные как есть.
    если вместо null надо вставить что-то еще, то использовать COALESCE
    Ответ написан
    Комментировать
  • Экранирование sql запросов, достаточно ли функции?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Эта функция не самописная, а цельнотянутая. Причем из самых смрадных помоек интернета.
    К защите от инъекций не имеет вообще никакого отношения.

    - trim() ни к инъекциям, ни к защите отношения не имеет
    - stripslashes() просто бессмысленная функция, которая только портит данные
    - htmlspecialchars() не имеет отношения к SQL. Применяется при выводе данных, а не при получении
    - real_escape_string() - единственная функция, которая имеет отношение к SQL, но при этом вообще не предназначенная ни для каких защит.

    Попробуйте на основании этой информации самостоятельно оценить полезность вашей функции.

    Возьмем классический пример
    $_GET['id'] = '1;DROP TABLE Students;';
    $id = formatstr($_GET['id']);
    $sql = "SELECT * FRPM Students WHERE id=$id";

    И посмотрим, помогло ли ваше самописное экранирование предотвратить хоть что-то (спойлер: нет).
    (да, та функция, которую лично вы используете для выполнения запросов, выполняет только один запрос за раз. И вместо инъекции вы получите ошибку. Но это не отменяет сам факт получения инъекции.)

    Как правильно все отметили выше, для защиты от инъекций используются подготовленные запросы, в которых все переменные заменяются на специальные маркеры, и передаются отдельно.
    Ответ написан
    Комментировать
  • Как правильно экранировать поля, содержащие разметку?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Если текст содержит HTML теги, которые должны выводиться как есть, то его не надо обрабатывать функцией, которая преобразует теги в HTML сущности.

    Если же вопрос про обработку данных перед их записью в БД, то надо задать себе вопрос, какое отношение функция htmlspecialchars имеет к базе данных.

    Логика - это просто незаменимый инструмент для программиста.
    Ответ написан
    5 комментариев
  • Как при выводе данных из базы модифицировать одно из полей?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    У вас каша в голове. И вы все делаете неправильно.
    Заменять теги на сущности надо не перед записью в БД, а перед выводом в HTML. Желательно - средствами этого "табулятора", если он это умеет.

    Никакой HTML в БД хранить нельзя.
    Любое HTML оформление надо добавлять средствами этого "табулятора".
    В самом крайнем случае - в ноде, перед выводом

    name: '<p>' + entities.encode(result.name) + '<p>'
    Хотя это конечно говнокод и кровь из глаз.
    Ответ написан
    2 комментария
  • Как использовать структуры данных на практике?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Мысль совершенно правильная.

    Современные высокоуровневые языки и системы управления данными чаще всего скрывают большую часть алгоритмов от пользователя, предоставляя готовое решение для большинства выполняемых операций.
    Плюс, большинство прикладных задач практически не требуют знакомства со сложными структурами данных и алгоритмами.
    Плюс мощность современных компьютеров очень часто прощает программисту ошибки и неоптимальные решения.

    Поэтому большая часть классических алгоритмов, все эти пузырьки со вставками, имеют скорее академическую ценность. И с психологической точки зрения только затрудняют обучение. Всегда сложнее учить сферического коня в вакууме, не подкрепленного практическими задачами.
    Но с другой стороны, все эти вещи развивают мозги, дают базу, которая потом, в дальнейшем, при переходе к более сложным задачам, сможет пригодиться.

    Поэтому я бы рекомендовал их все равно изучать, но в качестве не основного, а факультативного материала.
    Ответ написан
    Комментировать
  • Почему не работает sql запрос в Laravel?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Этот набор шаманских заклинаний помог потому, что в нем отсутствует элемент ONLY_FULL_GROUP_BY.
    Который и отвечает за строгость по отношению к вопросу о группировке.
    И по которому гуглится миллион объяснений заодно.
    Ответ написан
    Комментировать
  • Как оптимизировать пагинацию отсортированных по времени создания записей?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Ну, вариант "в лоб" это
    select * from table where date >= n and id not in (...) order by date limit 1000

    где n - это последняя дата с предыдущей страницы, а ... - это список id на ту же дату с той же страницы.

    Но как правильно пишут в комментариях, если пагинация начинает тормозить, то надо что-то в консерватории менять. И например разбивать не по 1000 строк, а по дате.
    Ответ написан
  • В запросе SQL в php условия в кавычках как?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Никогда не понимал любителей ломать пальцы обо все эти точечки-кавычечки-запяточечки. Это же надо так запариться, старательно после каждого слова выписывая пунктуацию. Есть же нормальные двойные кавычки.
    "mysqldump -u$user -p$password --single-transaction --force --opt --where 'ENTITY_FIELD = STATUS_ID AND ASSIGNED_BY_ID >0' $database $table > relations.sql"
    Ответ написан
  • Ошибка "Unexpected update count received …" при удалении строки в таблице БД в PhpStorm. Как решить?

    ipatiev
    @ipatiev Куратор тега PHP
    Потомок старинного рода Ипатьевых-Колотитьевых
    Решение простое: не забывать про первичный ключ в таблицах и не плодить дубли.
    Ответ написан
    Комментировать
  • Какую книгу прочитать про SQL?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    https://svyatoslav.biz/relational_databases_book/

    Про хинты надо знать только одно - если они нужны, значит есть проблемы в архитектуре.
    Ответ написан
    1 комментарий
  • Как правильно сделать запрос в бд?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Я даже не представляю, сколько раз на этот запрос здесь уже отвечали. Но разве ж тут что найдёшь...
    WHERE date BETWEEN '2021-10-01 00:00:00' and '2021-10-30 23:59:59'
    Ответ написан
    8 комментариев
  • Не могу выполнить sql INSERT yii2 mssql, как правильно составить INSERT?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Селект внутри values может возвращать только одно значение. Не несколько колонок, не несколько строк, а значение одной колонки одной строки.

    В целом запрос настолько бессмысленный, что из него даже непонятно, что вы вообще хотели сделать.
    Попробуйте написать это словами.
    Ответ написан
  • Как подобрать данные из локальной базы данных пользователя через Django?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Чтобы подключиться к удалённой БД, надо в её настройках разрешить удалённые соединения (bind_address) и добавить соответствующего пользователя. Плюс открыть порт на файрволле.
    Так же, если соединение происходит не через VPN, то очень желательно настроить SSL соединение.

    Но учитывая задачу, сама постановка вопроса неправильная. надо делать не входящие соединения на удалённые компьютеры, а исходящие с них.
    Ответ написан
  • Почему sql-оператор IN (в WHERE) плох с точки зрения оптимизации?

    ipatiev
    @ipatiev
    Потомок старинного рода Ипатьевых-Колотитьевых
    Использование оператора IN (значение0, значение1, значение2) никак не сказывается на производительности SQL-запроса.
    Чтобы запрос был менее ресурсозатратным, надо посмотреть результат EXPLAIN и расставить индексы.
    Ответ написан
    Комментировать