使用 Doctrine 2执行原始 SQL

我想使用 Doctrine 2执行原始 SQL

我需要截断数据库表并使用默认测试数据初始化表。

215019 次浏览

I found out the answer is probably:

NativeQuery 允许您执行本机 SQL,根据 你的规格。这样一个 specification that describes how an SQL 结果集映射到 Doctrine 结果由 ResultSetMapping.

资料来源: 本机 SQL

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


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

我遇到了同样的问题。您想查看由实体管理器提供的连接对象:

$conn = $em->getConnection();

You can then query/execute directly against it:

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

See the docs for the connection object at http://www.doctrine-project.org/api/dbal/2.0/doctrine/dbal/connection.html

下面是我正在执行的原始查询的一个例子:

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();
}

How to execute a raw Query and return the data.

Hook onto your manager and make a new connection:

$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']);

在您的模型中创建原始 SQL 语句(下面的例子是一个我必须使用但替换您自己的日期间隔的例子)。如果您正在对 execute ()调用执行 SELECT add-> fetchall ()。

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


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


$stmt->execute();

我通过这样做使它工作,假设你正在使用 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。

不行,原则2不允许原始查询。也许看起来你可以,但是如果你尝试这样做:

$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 业务。

这里的大多数答案在 原则 DBAL 2.13之后就不再适用了,例如 将不推荐执行,而 fetchAll 将在2022年被删除

/**
* BC layer for a wide-spread use-case of old DBAL APIs
*
* @deprecated This API is deprecated and will be removed after 2022
*
* @return list<mixed>
*/
public function fetchAll(int $mode = FetchMode::ASSOCIATIVE): array

不再推荐使用 executefetchAll,因为两者都不推荐使用。

* @deprecated Statement::execute() is deprecated, use Statement::executeQuery() or executeStatement() instead


* @deprecated Result::fetchAll is deprecated, and will be removed after 2022

因此,在执行原始 SQL 和获取结果时,我们必须更加具体。


我们需要使用 executeQueryexecuteStatement,而不是使用 Statement::execute()

ExecuteQuery 返回对象 Result:

使用当前绑定的参数执行语句并返回 结果。

ExecuteStatement 返回 int:

使用当前绑定的参数执行语句并返回受影响的行。


我们需要使用 fetchAllNumericfetchAllAssociative(and more)而不是使用 Result::fetchAll()


为了得到一个简单的结果,你必须这样做:

public function getSqlResult(EntityManagerInterface $em)
{
$sql = "
SELECT firstName,
lastName
FROM app_user
";


$stmt = $em->getConnection()->prepare($sql);
$result = $stmt->executeQuery()->fetchAllAssociative();
return $result;
}

And with parameters:

public function getSqlResult(EntityManagerInterface $em)
{
$sql = "
SELECT firstName,
lastName,
age
FROM app_user
where age >= :age
";


$stmt = $em->getConnection()->prepare($sql);
$stmt->bindParam('age', 18);
$result = $stmt->executeQuery()->fetchAllAssociative();
return $result;
}