我想使用 Doctrine 2 执行原始 SQL
我需要截断数据库表并使用默认测试数据初始化表。
这是我正在执行的原则 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();
}
//$sql - sql statement
//$em - entity manager
$em->getConnection()->exec( $sql );
假设您正在使用 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 以满足您的需要。
自 Doctrine DBAL 2.13 起,这里的大多数答案现已被弃用。例如,execute 已被弃用,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
不再建议先使用
execute
,然后使用 fetchAll
,因为两者均已弃用。
* @deprecated Statement::execute() is deprecated, use Statement::executeQuery() or executeStatement() instead
* @deprecated Result::fetchAll is deprecated, and will be removed after 2022
因此,在执行原始 SQL 以及获取结果时,我们必须更加具体。
我们需要使用
Statement::execute()
或 executeQuery
,而不是使用 executeStatement
。
executeQuery返回对象
Result
:
使用当前绑定的参数执行语句并返回 结果。
executeStatement返回
int
:
使用当前绑定的参数执行语句并返回受影响的行。
我们需要使用
Result::fetchAll()
或 fetchAllNumeric
(以及更多),而不是使用
fetchAllAssociative
。
要获得简单的结果,您必须这样做:
public function getSqlResult(EntityManagerInterface $em)
{
$sql = "
SELECT firstName,
lastName
FROM app_user
";
$stmt = $em->getConnection()->prepare($sql);
$result = $stmt->executeQuery()->fetchAllAssociative();
return $result;
}
并带有参数:
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;
}
联系您的经理并建立新的联系:
$manager = $this->getDoctrine()->getManager();
$conn = $manager->getConnection();
创建查询并获取全部:
$result= $conn->query('select foobar from mytable')->fetchAll();
从结果中获取数据,如下所示:
$this->appendStringToFile("first row foobar is: " . $result[0]['foobar']);
我发现答案可能是:
NativeQuery 可让您执行本机 SQL,根据映射结果 您的规格。这样一个 规范描述了如何 SQL结果集映射到Doctrine 结果由一个表示 结果集映射。
来源:本机 SQL。
我也有同样的问题。您想要查看实体管理器提供的连接对象:
$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
在您的模型中创建原始 SQL 语句(下面的示例是我必须使用但替换为您自己的日期间隔的示例。如果您正在执行 SELECT,则将 ->fetchall() 添加到execute() 调用中。
$sql = "DELETE FROM tmp
WHERE lastedit + INTERVAL '5 minute' < NOW() ";
$stmt = $this->getServiceLocator()
->get('Doctrine\ORM\EntityManager')
->getConnection()
->prepare($sql);
$stmt->execute();
你不能,Doctrine 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 业务。
我正在使用
2.15.4
的 doctrine/orm
,并假设代码中的 $entityManager
是 Doctrine\ORM\EntityManagerInterface
的实例。
当您想要执行原始 SQL 查询时,有两种情况:
1。查询结果无关紧要,可以忽略
这似乎与原始问题相符,可以使用以下代码片段:
$sqls = [
'DROP TABLE IF EXISTS _performance_test',
'CREATE TABLE _performance_test (counter BIGINT UNSIGNED NOT NULL)',
'INSERT INTO _performance_test (counter) VALUES (0)',
];
$connection = $entityManager->getConnection();
foreach ($sqls as $sql) {
$connection->executeStatement($sql);
}
2。查询结果很重要并且被使用
$sql = 'SELECT counter FROM _performance_test LIMIT 1';
$result = $entityManager->getConnection()->prepare($sql)->executeQuery();
在本例中,
$result
是Doctrine\DBAL\Result
的实例,您可以调用它的任何方法(fetchAssociative
、fetchOne
、fetchAllAssociative
等)。示例:
$counter = $result->fetchOne();