À propos, lorsque je veux faire du travail de base de données automatisé, comme faire des mysqldumps ou charger des données à partir de vidages précédents ou de supprimer des tables, j'écris généralement un script shell pour ce travail, puis j'écris une tâche (ou "commande", en langage Symfony2 ) qui exécute le script shell. Le but d'un ORM, tel que je le comprends, est d'abstraire le travail répétitif, et si vous faites quelque chose comme tronquer un tableau, je ne vois pas en quoi il serait logique de mettre la Doctrine en scène puisque la Doctrine ne le fait pas. t rendre cette tâche plus facile.
Jason Swett
Réponses:
164
Voici un exemple de requête brute dans Doctrine 2 que je fais:
Bonne réponse. Pour obtenir le gestionnaire d'entités dans ce code, vous pouvez utiliser $ this-> getDoctrine () -> getManager () à la place de ce code au-dessus de "$ this-> getEntityManager ()" , de cette façon cela a fonctionné pour moi tout de suite.
webblover
hey, ça me donne Appel à la méthode indéfinie Index :: getDoctrine () que dois-je faire
Cela m'a conduit dans la bonne direction mais ce n'était pas exactement ce dont j'avais besoin. Je soupçonne que l'âge de la réponse fait une différence. J'ai utilisé: ...getConnection()->query($sql);et je n'ai pas eu à courir$stmt->execute();
Brandon
Notez qu'avec Symfony4 et l'autowiring, vous pouvez taper un indice EntityManagerInterface $entityManagerpuis appeler$entityManager->getConnection()
Aussi une bonne idée d'appeler prepare () au lieu d'exec afin de pouvoir toujours obtenir le support des instructions préparées.
Jeremy Hicks
44
Je l'ai fait fonctionner en faisant cela, en supposant que vous utilisez 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);
Vous pouvez modifier le FETCH_TYPE en fonction de vos besoins.
query () est utilisé lorsque le SQL renvoie certaines données que vous souhaitez utiliser; exec () est pour quand ce n'est pas le cas
Jeffiekins
12
J'ai découvert que la réponse est probablement:
Un NativeQuery vous permet d'exécuter du SQL natif, en mappant les résultats selon vos spécifications. Une telle spécification qui décrit comment un jeu de résultats SQL est mappé à un résultat Doctrine est représentée par un ResultSetMapping.
C'est la réponse acceptée mais je ne vois toujours pas en quoi cette partie de Doctrine est utile car vous avez toujours besoin du ResultSetMapping. Je ne veux pas qu'il mappe les résultats aux entités .... qui par défaut le point d'exécuter SQL arbitraire!
De plus, le SQL natif non natif n'exécutera pas toutes les requêtes SQL possibles. DELETE / UPDATE / INSERT ne fonctionnera pas, ni certaines définitions de table qui ne suivent pas les hypothèses de doctrine. (Table de jonction M2M sans ID). Cette réponse n'est donc pas universelle. Il ne devrait pas non plus être accepté car les INSERT ne fonctionneront pas.
przemo_li
5
J'ai eu le même problème. Vous souhaitez consulter l'objet de connexion fourni par le gestionnaire d'entités:
$conn = $em->getConnection();
Vous pouvez ensuite interroger / exécuter directement contre lui:
$statement = $conn->query('select foo from bar');
$num_rows_effected = $conn->exec('update bar set foo=1');
Dans votre modèle, créez l'instruction SQL brute (l'exemple ci-dessous est un exemple d'intervalle de date que j'ai dû utiliser mais que je remplace le vôtre. Si vous effectuez un SELECT, ajoutez -> fetchall () à l'appel execute ().
$sql ="DELETE FROM tmp
WHERE lastedit + INTERVAL '5 minute' < NOW() ";
$stmt = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager')->getConnection()->prepare($sql);
$stmt->execute();
Vous ne pouvez pas, Doctrine 2 ne permet pas les requêtes brutes. Cela peut sembler possible, mais si vous essayez quelque chose comme ceci:
$sql ="SELECT DATE_FORMAT(whatever.createdAt, '%Y-%m-%d') FORM whatever...";
$em = $this->getDoctrine()->getManager();
$em->getConnection()->exec($sql);
La doctrine crachera une erreur disant que DATE_FORMAT est une fonction inconnue.
Mais ma base de données (mysql) connaît cette fonction, donc fondamentalement, ce qui se passe, c'est que Doctrine analyse cette requête dans les coulisses (et derrière votre dos) et trouve une expression qu'elle ne comprend pas, considérant que la requête est invalide.
Donc, si comme moi vous voulez pouvoir simplement envoyer une chaîne à la base de données et la laisser s'en occuper (et laisser le développeur prendre l'entière responsabilité de la sécurité), oubliez-la.
Bien sûr, vous pouvez coder une extension pour autoriser cela d'une manière ou d'une autre, mais vous pouvez tout aussi bien utiliser mysqli pour le faire et laisser Doctrine à son activité ORM.
mysqldump
s ou charger des données à partir de vidages précédents ou de supprimer des tables, j'écris généralement un script shell pour ce travail, puis j'écris une tâche (ou "commande", en langage Symfony2 ) qui exécute le script shell. Le but d'un ORM, tel que je le comprends, est d'abstraire le travail répétitif, et si vous faites quelque chose comme tronquer un tableau, je ne vois pas en quoi il serait logique de mettre la Doctrine en scène puisque la Doctrine ne le fait pas. t rendre cette tâche plus facile.Réponses:
Voici un exemple de requête brute dans Doctrine 2 que je fais:
la source
...getConnection()->query($sql);
et je n'ai pas eu à courir$stmt->execute();
EntityManagerInterface $entityManager
puis appeler$entityManager->getConnection()
la source
Je l'ai fait fonctionner en faisant cela, en supposant que vous utilisez PDO.
Vous pouvez modifier le FETCH_TYPE en fonction de vos besoins.
la source
Comment exécuter une requête brute et renvoyer les données.
Accrochez-vous à votre manager et établissez une nouvelle connexion:
Créez votre requête et fetchAll:
Obtenez les données du résultat comme ceci:
la source
J'ai découvert que la réponse est probablement:
Source: SQL natif .
la source
J'ai eu le même problème. Vous souhaitez consulter l'objet de connexion fourni par le gestionnaire d'entités:
Vous pouvez ensuite interroger / exécuter directement contre lui:
Consultez la documentation de l'objet de connexion à l' adresse http://www.doctrine-project.org/api/dbal/2.0/doctrine/dbal/connection.html
la source
Dans votre modèle, créez l'instruction SQL brute (l'exemple ci-dessous est un exemple d'intervalle de date que j'ai dû utiliser mais que je remplace le vôtre. Si vous effectuez un SELECT, ajoutez -> fetchall () à l'appel execute ().
la source
Vous ne pouvez pas, Doctrine 2 ne permet pas les requêtes brutes. Cela peut sembler possible, mais si vous essayez quelque chose comme ceci:
La doctrine crachera une erreur disant que DATE_FORMAT est une fonction inconnue.
Mais ma base de données (mysql) connaît cette fonction, donc fondamentalement, ce qui se passe, c'est que Doctrine analyse cette requête dans les coulisses (et derrière votre dos) et trouve une expression qu'elle ne comprend pas, considérant que la requête est invalide.
Donc, si comme moi vous voulez pouvoir simplement envoyer une chaîne à la base de données et la laisser s'en occuper (et laisser le développeur prendre l'entière responsabilité de la sécurité), oubliez-la.
Bien sûr, vous pouvez coder une extension pour autoriser cela d'une manière ou d'une autre, mais vous pouvez tout aussi bien utiliser mysqli pour le faire et laisser Doctrine à son activité ORM.
la source