CakePHP 3 Raw SQL Query

Я использую CakePHP 3, мне нужно выполнить сырой запрос SQL для нескольких таблиц. В CakePHP 2 это можно сделать с помощью метода query () в любой модели ( $this->Messages->query("select..") ).

Мне нужен метод, который позволяет мне выполнять запрос SQL в CakePHP 3. Ниже приведен фрагмент кода, который я использую:

$aumTable = TableRegistry::get('Messages');
$sql = "SELECT (SELECT COUNT(*) FROM `messages`) AS `Total_Count`,
(SELECT COUNT(*) FROM `messages_output`) AS `Total_Output_Count`,
(SELECT COUNT(*) FROM `messages_output` WHERE `is_success`=1) AS `Total_Successful_Output_Count`,
(SELECT COUNT(*) FROM `messages_output` WHERE `is_success`=0) AS `Total_Error_Output_Count`,
(SELECT COUNT(*) FROM `users`) AS `Total_User_Count`;";

// to run this raw SQL query what method should i use? query() doesn't work..
// $result = $aumTable->query($sql); ??
// $result = $aumTable->sql($sql); ??

Если вы можете предоставить ссылки на документацию по модели CakePHP 3, где я могу найти эту информацию, это тоже будет полезно. Я пытался искать в Google, но мог найти только вопросы, связанные с CakePHP 2.

10

Решение

Сначала вам нужно добавить ConnectionManager:

use Cake\Datasource\ConnectionManager;

Тогда вам нужно установить соединение следующим образом:

// my_connection is defined in your database config
$conn = ConnectionManager::get('my_connection');

Больше информации: http://book.cakephp.org/3.0/en/orm/database-basics.html#creating-connections-at-runtime

После этого вы можете запустить собственный запрос, например:

$stmt = $conn->execute('UPDATE posts SET published = ? WHERE id = ?', [1, 2]);

Больше информации: http://book.cakephp.org/3.0/en/orm/database-basics.html#executing-queries

И тогда вы готовы получить ряд (ы), как это:

// Read one row.
$row = $stmt->fetch('assoc');

// Read all rows.
$rows = $stmt->fetchAll('assoc');

// Read rows through iteration.
foreach ($rows as $row) {
// Do work
}

Больше информации: http://book.cakephp.org/3.0/en/orm/database-basics.html#executing-fetching-rows

25

Другие решения

Документация для этого здесь: http://book.cakephp.org/3.0/en/orm/database-basics.html#executing-queries

Но что там не написано, так это как выполнить. Поскольку это стоило мне времени, вот решение для этого:

1. Вам нужно добавить

use Cake\Datasource\ConnectionManager;

2. В ConnectionManager (как указано выше)

$conn = ConnectionManager::get('my_connection');

3. Выполните ваш SQL с помощью чего-то вроде этого

$firstName = $conn->execute('SELECT firstname FROM users WHERE id = 1');
12

Вопрос уже очень старый, но я до сих пор нахожу его часто.
Вот решение для CAKEPHP 3.6 и (сокращенно) для более новых версий PHP.

Нет необходимости использовать функцию get ConnectionManager, и часто это не имеет смысла, так как имя соединения может быть неизвестно вообще. Каждая таблица имеет свое / соединение, которое можно получить с помощью getConnection ().

Если вы уже в таблице сообщений (src/Model/Table/MessagesTable.php), вы можете просто использовать соединение

$con = $this->Messages->getConnection();

Если вы не там (что ваш код будет предлагать с TableRegistry::get()Вы можете сделать это и с этой таблицей

// $aumTable is declared in question
$con = $aumTable->getConnection();

тогда вы можете выполнить запрос RAW, как показано выше:

$result = $con->execute ();
// short
$result = $this->Messages->getConnection()->execute ('Select * from ...')
// or ($aumTable is declared in question)
$result = $aumTable->getConnection()->execute ('Select * from ...');
0