DAO добавить в IN значения

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Alex21
Сообщения: 39
Зарегистрирован: 2016.11.11, 09:27

DAO добавить в IN значения

Сообщение Alex21 »

Добрый день!
Создаю запросы к бд MySQL через DAO. Голову сломал, пытаясь вставить в IN последовательность значений.

Код: Выделить всё

$diskTypes_command = Yii::$app->db->createCommand('SELECT id FROM disk_type WHERE name IN (:result_disk_types)');
$diskTypes_command->bindValue(':result_disk_types', $result_disk_types);
$diskTypes_query = $diskTypes_command->queryAll();
Изначально приходит массив, составлял строку вида: 'значение 1', 'значение 2'. Не прокатывает. Если просто вставляешь IN ('значение 1', 'значение 2') - работает, если через bindValue передаешь строку 'значение 1', 'значение 2' - не работает.
steaze
Сообщения: 30
Зарегистрирован: 2017.01.28, 21:25

Re: DAO добавить в IN значения

Сообщение steaze »

Как-то так:

Код: Выделить всё

$result_disk_types = ['type1', 'type2'];
$diskTypes_query = Yii::$app->db->createCommand('SELECT id FROM disk_type WHERE name IN :result_disk_types')
->bindValue(':result_disk_types', $result_disk_types);
->queryAll();
Alex21
Сообщения: 39
Зарегистрирован: 2016.11.11, 09:27

Re: DAO добавить в IN значения

Сообщение Alex21 »

steaze писал(а): 2017.07.01, 18:24 Как-то так:

Код: Выделить всё

$result_disk_types = ['type1', 'type2'];
$diskTypes_query = Yii::$app->db->createCommand('SELECT id FROM disk_type WHERE name IN :result_disk_types')
->bindValue(':result_disk_types', $result_disk_types);
->queryAll();
Так тоже пробовал, результат:
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''Array'' at line 1
The SQL being executed was: SELECT id FROM disk_type WHERE name IN Array
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: DAO добавить в IN значения

Сообщение mkramer »

Воспользуйтесь Query Builder

Код: Выделить всё

$diskTypes = (new \yii\db\Query)->from("disk_type")->select("id")->where(["name"=>$result_disk_types])->column();
Тогда Yii сам позаботится о массиве. А то, что вы пишите, транслируется прямо в PDO, а PDO сам не умеет подставлять массивы

http://www.yiiframework.com/doc-2.0/gui ... ilder.html
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: DAO добавить в IN значения

Сообщение zelenin »

Alex21 писал(а): 2017.07.01, 17:07 Добрый день!
Создаю запросы к бд MySQL через DAO. Голову сломал, пытаясь вставить в IN последовательность значений.

Код: Выделить всё

$diskTypes_command = Yii::$app->db->createCommand('SELECT id FROM disk_type WHERE name IN (:result_disk_types)');
$diskTypes_command->bindValue(':result_disk_types', $result_disk_types);
$diskTypes_query = $diskTypes_command->queryAll();
Изначально приходит массив, составлял строку вида: 'значение 1', 'значение 2'. Не прокатывает. Если просто вставляешь IN ('значение 1', 'значение 2') - работает, если через bindValue передаешь строку 'значение 1', 'значение 2' - не работает.
биндить можно только скаляры.
Alex21
Сообщения: 39
Зарегистрирован: 2016.11.11, 09:27

Re: DAO добавить в IN значения

Сообщение Alex21 »

Спасибо вам всем большое за ответы. Думаю использовать Query Builder, как посоветовал mkramer. Еще остался вопрос, что быстрее DAO или Query Builder, будет ли проигрыш в скорости работы?
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: DAO добавить в IN значения

Сообщение mkramer »

QueryBuilder - это надстройка над DAO, так что не будет видимого проигрыша в скорости. Это ещё не ActiveRecord, который этот проигрыш даёт, поскольку там гораздо больше надстроено над запросами. Но тоже, значимый проигрыш по скорости ActiveRecord будет давать при большой нагрузке на сайт, для небольших сайтов с потенциально небольшим количеством посетителей очень удобно использовать, хотя и говорят, что это антипаттерн.
Alex21
Сообщения: 39
Зарегистрирован: 2016.11.11, 09:27

Re: DAO добавить в IN значения

Сообщение Alex21 »

mkramer писал(а): 2017.07.01, 20:32 QueryBuilder - это надстройка над DAO, так что не будет видимого проигрыша в скорости. Это ещё не ActiveRecord, который этот проигрыш даёт, поскольку там гораздо больше надстроено над запросами. Но тоже, значимый проигрыш по скорости ActiveRecord будет давать при большой нагрузке на сайт, для небольших сайтов с потенциально небольшим количеством посетителей очень удобно использовать, хотя и говорят, что это антипаттерн.
Спасибо за помощь! Значит буду использовать QueryBuilder. ActiveRecord использовал в другом проекте, по удобству его использования мне он тоже понравился.
Restlin
Сообщения: 139
Зарегистрирован: 2011.09.09, 18:12

Re: DAO добавить в IN значения

Сообщение Restlin »

У ActiveRecord тоже есть возможность делать запросы с IN из массива.
Точнее это у ActiveQuery, который отвечает за поиск.
DiskType::find()->andWhere(['name' => $result_disk_types])->all();
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: DAO добавить в IN значения

Сообщение mkramer »

Restlin писал(а): 2017.07.01, 23:29 У ActiveRecord тоже есть возможность делать запросы с IN из массива.
Естественно. Он же в случае Yii2 надстройка, в свою очередь, над QueryBuilder. Но там ещё много чего добавлено
Restlin
Сообщения: 139
Зарегистрирован: 2011.09.09, 18:12

Re: DAO добавить в IN значения

Сообщение Restlin »

mkramer писал(а): 2017.07.02, 10:15
Restlin писал(а): 2017.07.01, 23:29 У ActiveRecord тоже есть возможность делать запросы с IN из массива.
Естественно. Он же в случае Yii2 надстройка, в свою очередь, над QueryBuilder. Но там ещё много чего добавлено
Я понимаю это, это было сообщение для ТС, мне кажется как раз он не понимает всей иерархии классов для работы с БД.
Alex21
Сообщения: 39
Зарегистрирован: 2016.11.11, 09:27

Re: DAO добавить в IN значения

Сообщение Alex21 »

Добрый день. Возник вопрос по построителю запросов. Не пойму, как составить запрос вида:

Код: Выделить всё

SELECT
  birthday,
  (
    (YEAR(CURRENT_DATE) - YEAR(birthday)) -                             /* step 1 */
    (DATE_FORMAT(CURRENT_DATE, '%m%d') < DATE_FORMAT(birthday, '%m%d')) /* step 2 */
  ) AS age
FROM users
mkramer
Сообщения: 531
Зарегистрирован: 2014.12.14, 13:02

Re: DAO добавить в IN значения

Сообщение mkramer »

Besides column names, you can also select DB expressions. You must use the array format when selecting a DB expression that contains commas to avoid incorrect automatic name quoting. For example,

$query->select(["CONCAT(first_name, ' ', last_name) AS full_name", 'email']);
http://www.yiiframework.com/doc-2.0/gui ... tml#select - когда что-то не знаешь, идёшь в документацию
Ответить