Использование Raw SQL с Doctrine

У меня есть несколько чрезвычайно сложных запросов, которые мне нужно использовать для создания отчета в моем приложении. Я использую symfony как свою структуру и доктрину как свою ORM.

У меня такой вопрос:

Как лучше всего передавать очень сложные sql-запросы непосредственно в Doctrine, не конвертируя их в язык запросов Doctrine? Я читал о расширении Raw_SQL, но похоже, что вам все равно нужно передавать запрос по разделам (например, from()). Есть ли что-нибудь для того, чтобы просто сбросить кучу сырых команд sql?


person Levi Hackwith    schedule 05.05.2010    source источник
comment
Извините, что не по теме, но какой инструмент / библиотеку вы используете для создания отчетов по вашему приложению? С наилучшими пожеланиями!   -  person Rui Gonçalves    schedule 08.05.2010
comment
Сейчас? Просто SQL, чистый PHP и галл. : D   -  person Levi Hackwith    schedule 09.05.2010


Ответы (6)


$q = Doctrine_Manager::getInstance()->getCurrentConnection();
$result = $q->execute(" -- RAW SQL HERE -- ");

См. Документацию по API Doctrine для получения информации о различных методах выполнения.

person Tom    schedule 05.05.2010
comment
@simple: Да, вы можете использовать любой SQL, какой захотите. - person Tom; 27.11.2010
comment
Поскольку этот ответ кажется популярным, я должен добавить, что этот метод обходит экранирование, предлагаемое Doctrine, поэтому избегайте вещей вручную, или вы можете оставить себя открытыми для отверстий для SQL-инъекций. - person Tom; 01.11.2011
comment
Мне кажется, что это ответ для версии Doctrine ‹2. Для необработанных запросов в Doctrine 2 я нашел этот пост полезным: forum.symfony-project.org/viewtopic.php?f=23&t=37872 - person Jason Swett; 30.03.2012
comment
Я обнаружил, что добавление - ›getDbh () как в ответе @ richsage предотвращает появление предупреждений, когда включен профилировщик доктрины. - person cmc; 18.05.2015

да. Вы можете получить дескриптор базы данных из Doctrine, используя следующий код:

$pdo = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh();

а затем выполните свой SQL следующим образом:

$query = "SELECT * FROM table WHERE param1 = :param1 AND param2 = :param2";
$stmt = $pdo->prepare($query);

$params = array(
  "param1"  => "value1",
  "param2"  => "value2"
);
$stmt->execute($params);

$results = $stmt->fetchAll();  

Вы можете использовать связанные переменные, как в приведенном выше примере.

Обратите внимание, что Doctrine не будет автоматически преобразовывать ваши результаты в объекты записи и т. Д., Поэтому вам нужно будет иметь дело с результатами, возвращаемыми в виде массива, состоящего из одного массива на каждую возвращаемую строку (значение ключа как значение столбца).

person richsage    schedule 05.05.2010
comment
Есть ли способ заставить доктрину гидратировать результаты, которые я получаю через PDO? или мне просто нужно работать с тем, что мне дано? - person Levi Hackwith; 05.05.2010
comment
По памяти, когда я использовал вышеупомянутое, не автоматически, поскольку Doctrine не знает, какие столбцы у вас есть. Если вы достаточно хорошо назвали столбцы, я думаю, вы могли бы использовать fromArray () или аналогичный, но данные нужно будет переформатировать во что-то, что можно использовать для этого. - person richsage; 06.05.2010
comment
Если можете, используйте свой запрос для возврата идентификатора записи, а затем используйте старый добрый $ table- ›find ($ id) для его загрузки. - person lotsoffreetime; 06.05.2010

Я не уверен, что вы имеете в виду, говоря необработанный SQL, но вы можете выполнять традиционные SQL-запросы следующим образом:

... 
// $this->_displayPortabilityWarning();

$conn = Doctrine_Manager::connection();
$pdo = $conn->execute($sql);
$pdo->setFetchMode(Doctrine_Core::FETCH_ASSOC);
$result = $pdo->fetchAll();
...

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

protected function _displayPortabilityWarning($engine = 'pgsql')
{
     $conn = Doctrine_Manager::connection();
     $driver = $conn->getDriverName();

     if (strtolower($engine) != strtolower($driver)) {
        trigger_error('Here we have possible database portability issue. This code was tested on ' . $engine . ' but you are trying to run it on ' . $driver, E_USER_NOTICE);
     }
}
person takeshin    schedule 05.05.2010

Вы также можете использовать Doctrine_RawSql (); для создания необработанных SQL-запросов, которые будут преобразованы в объекты доктрины.

person Twelve47    schedule 03.06.2010

Следует отметить, что Doctrine2 использует PDO в качестве основы, поэтому я бы рекомендовал использовать подготовленные операторы вместо простого старого выполнения.

Пример:

$db = Doctrine_Manager::getInstance()->getCurrentConnection();
$query = $db->prepare("SELECT `someField` FROM `someTable` WHERE `field` = :value");
$query->execute(array('value' => 'someValue'));
person Nikola Petkanski    schedule 08.12.2011
comment
Этот вопрос касается Symfony 1. На Symfony 1 используется Doctrine 1.2 - этот ответ может вводить в заблуждение. - person xmc; 28.02.2013
comment
Извините, я не хотел вводить в заблуждение. Решение все еще актуально, поскольку Symfony 1 также может использоваться с Doctrine. - person Nikola Petkanski; 28.02.2013

Symfony вставляет необработанный sql с помощью doctrine.

Это в версии Symfoney 1.3

$q = Doctrine_Manager::getInstance()->getCurrentConnection();
$result = $q->execute($query);
person SMSM    schedule 19.01.2013