Doctrine 2を使用して生のSQLを実行する


102

Doctrine 2を使用して生のSQLを実行したい

データベーステーブルを切り捨て、テーブルをデフォルトのテストデータで初期化する必要があります。


2
ちなみに、mysqldumpsを実行したり、以前のダンプからデータを読み込んだり、テーブルをドロップしたりするなど、自動データベースグラントワークを実行する場合は、通常、その作業用のシェルスクリプトを記述してから、タスク(または「コマンド」、Symfony2言語で記述します)シェルスクリプトを実行します。私が理解しているように、ORMの目的は反復作業を抽象化することです。Doctrineがそうではないので、Doctrineを図に組み込むことが理にかなっているかわかりません。 tそのタスクをもっと簡単にします。
Jason Swett、2012年

回答:


164

これが私がやっているDoctrine 2の生のクエリの例です:

public function getAuthoritativeSportsRecords()
{   
    $sql = " 
        SELECT name,
               event_type,
               sport_type,
               level
          FROM vnn_sport
    ";

    $em = $this->getDoctrine()->getManager();
    $stmt = $em->getConnection()->prepare($sql);
    $stmt->execute();
    return $stmt->fetchAll();
}   

4
素敵な答え。このコードでエンティティマネージャーを取得するには、このコードの代わりに「$ this-> getEntityManager()」の代わりに$ this-> getDoctrine()-> getManager()を使用できます。
webblover 2014

ちょっとその私が何をすべきか、未定義のメソッドインデックス:: getDoctrine()の呼び出しを与える
デクスター

私はドクトリン2でcodeigniter
Dexter

1
これは正しい方向に導いてくれましたが、私が必要としていたものとは正確には異なりました。答えの時代が違いを生むのではないかと思います。私が使用しました:...getConnection()->query($sql);実行する必要はありませんでした$stmt->execute();
ブランドン

Symfony4と自動配線では、ヒントEntityManagerInterface $entityManagerを入力してから呼び出すことができることに注意してください$entityManager->getConnection()
COil

50
//$sql - sql statement
//$em - entity manager

$em->getConnection()->exec( $sql );

18
また、execの代わりにprepare()を呼び出すことをお勧めします。これにより、準備されたステートメントのサポートを引き続き利用できます。
Jeremy Hicks

44

私は、PDOを使用していることを前提として、これを実行することでそれを機能させました。

//Place query here, let's say you want all the users that have blue as their favorite color
$sql = "SELECT name FROM user WHERE favorite_color = :color";

//set parameters 
//you may set as many parameters as you have on your query
$params['color'] = blue;


//create the prepared statement, by getting the doctrine connection
$stmt = $this->entityManager->getConnection()->prepare($sql);
$stmt->execute($params);
//I used FETCH_COLUMN because I only needed one Column.
return $stmt->fetchAll(PDO::FETCH_COLUMN);

ニーズに合わせてFETCH_TYPEを変更できます。


1
それらすべての中で最も良い例
デビッド

14

生のクエリを実行してデータを返す方法。

マネージャーに接続して、新しい接続を作成します。

$manager = $this->getDoctrine()->getManager();
$conn = $manager->getConnection();

クエリを作成してfetchAll:

$result= $conn->query('select foobar from mytable')->fetchAll();

このような結果からデータを取得します。

$this->appendStringToFile("first row foobar is: " . $result[0]['foobar']);

1
query()は、SQLが使用するデータを返す場合に使用します。exec()は、そうでない場合に使用します
Jeffiekins 2018年

12

答えはおそらく次のとおりです:

NativeQueryを使用すると、ネイティブSQLを実行し、指定に従って結果をマッピングできます。SQL結果セットがDoctrineの結果にどのようにマッピングされるかを記述するこのような仕様は、ResultSetMappingによって表されます。

ソース:ネイティブSQL


17
これは受け入れられた答えですが、ResultSetMappingは常に必要なので、Doctrineのこの部分がどのように役立つかはまだわかりません。結果をEntitiesにマッピングしたくありません....任意のSQLを実行するポイントをデフォルトにします!
MikeMurko

2
@MikeMurkoこの投稿は、Doctrine 2で生のクエリを実行するのに役立ちました。forum.symfony
Jason Swett

また、非ネイティブネイティブSQLは、考えられるすべてのSQLクエリを実行するわけではありません。DELETE / UPDATE / INSERTは機能せず、教義の前提に従わない一部のテーブル定義も機能しません。(IDなしのM2M結合テーブル)。したがって、この答えは普遍的ではありません。INSERTが機能しないため、受け入れるべきではありません。
przemo_li 2015年

5

私も同じ問題を抱えていました。エンティティマネージャによって提供された接続オブジェクトを調べたいと思います:

$conn = $em->getConnection();

その後、それに対して直接クエリ/実行できます。

$statement = $conn->query('select foo from bar');
$num_rows_effected = $conn->exec('update bar set foo=1');

http://www.doctrine-project.org/api/dbal/2.0/doctrine/dbal/connection.htmlにある接続オブジェクトのドキュメントを参照してください


5

モデルで生のSQLステートメントを作成します(以下の例は、私が使用しなければならない日付間隔の例ですが、独自のものを使用してください。SELECTを実行している場合は、execute()呼び出しに-> fetchall()を追加してください。

   $sql = "DELETE FROM tmp 
            WHERE lastedit + INTERVAL '5 minute' < NOW() ";

    $stmt = $this->getServiceLocator()
                 ->get('Doctrine\ORM\EntityManager')
                 ->getConnection()
                 ->prepare($sql);

    $stmt->execute();

4

できません。Doctrine2は生のクエリを許可していません。それはあなたができるように見えるかもしれませんが、あなたがこのようなことをしようとすると:

$sql = "SELECT DATE_FORMAT(whatever.createdAt, '%Y-%m-%d') FORM whatever...";
$em = $this->getDoctrine()->getManager();
$em->getConnection()->exec($sql);

DoctrineはDATE_FORMATが未知の関数であるというエラーを吐きます。

しかし、私のデータベース(mysql)はその機能を知っているので、基本的には、Doctrineがそのクエリをバックグラウンド(および背後)で解析し、クエリが無効であると見なして、理解できない式を見つけていることを確認しています。

したがって、私のように、単にデータベースに文字列を送信してそれを処理できるようにしたい(そして開発者にセキュリティの全責任を任せたい)場合は、それを忘れてください。

もちろん、何らかの方法でそれを許可するように拡張機能をコーディングすることもできますが、mysqliを使用してそれを行い、DoctrineをORMビジネスに任せることもできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.