使用Doctrine 2执行原始SQL

Jie*_*eng 96 php sql doctrine

我想使用Doctrine 2执行原始SQL

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

Jas*_*ett 158

这是我正在做的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();
}   
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案.要在此代码中获取实体管理器,您可以使用**$ this-> getDoctrine() - > getManager()**代替上面的代码**"$ this-> getEntityManager()"**,这样一来马上为我工作. (4认同)
  • 这引导我走向正确的方向,但并不完全是我所需要的。我怀疑答案的年龄会产生影响。我使用: `...getConnection()->query($sql);` 并且不必运行 `$stmt->execute();` (2认同)

oro*_*edd 50

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

$em->getConnection()->exec( $sql );
Run Code Online (Sandbox Code Playgroud)

  • 同样最好调用prepare()而不是exec,这样你仍然可以获得准备好的语句支持. (17认同)
  • **已弃用**:`exec`、`execute` 和 `fetchAll` 在 **Doctrine DBAL >2.13** 中已弃用,[有关更多信息,请参阅我的答案。](/sf/answers/4891962911/ /11350193) (2认同)

fer*_*dof 40

假设你正在使用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);
Run Code Online (Sandbox Code Playgroud)

您可以更改FETCH_TYPE以满足您的需求.


Dyl*_*Kas 20

自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
Run Code Online (Sandbox Code Playgroud)

不再建议使用executeand then,fetchAll因为两者均已弃用。

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

* @deprecated Result::fetchAll is deprecated, and will be removed after 2022
Run Code Online (Sandbox Code Playgroud)

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


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

执行查询返回对象Result

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

执行语句返回int

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


Result::fetchAll()我们需要使用fetchAllNumericor fetchAllAssociative以及更多),而不是使用。


要获得简单的结果,您必须执行以下操作:

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

    $stmt = $em->getConnection()->prepare($sql);
    $result = $stmt->executeQuery()->fetchAllAssociative();
    return $result;
}   
Run Code Online (Sandbox Code Playgroud)

并带有参数:

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;
}   
Run Code Online (Sandbox Code Playgroud)


Eri*_*ski 13

如何执行原始查询并返回数据.

连接到您的经理并建立新连接:

$manager = $this->getDoctrine()->getManager();
$conn = $manager->getConnection();
Run Code Online (Sandbox Code Playgroud)

创建您的查询和fetchAll:

$result= $conn->query('select foobar from mytable')->fetchAll();
Run Code Online (Sandbox Code Playgroud)

从结果中获取数据,如下所示:

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


Jie*_*eng 12

我发现答案很可能是:

NativeQuery允许您执行本机SQL,根据您的规范映射结果.描述如何将SQL结果集映射到Doctrine结果的这种规范由ResultSetMapping表示.

来源:Native SQL.

  • 这是公认的答案,但我仍然没有看到Doctrine的这一部分是如何有用的,因为你总是需要ResultSetMapping.我不希望它将结果映射到实体....这默认运行任意SQL的点! (16认同)
  • @MikeMurko我发现这篇文章对于在Doctrine 2中运行原始查询很有帮助:http://forum.symfony-project.org/viewtopic.php?f = 23&t = 37872 (2认同)

Tob*_*tch 5

我有同样的问题.您想查看实体管理器提供的连接对象:

$conn = $em->getConnection();
Run Code Online (Sandbox Code Playgroud)

然后,您可以直接查询/执行它:

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

请参阅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();
Run Code Online (Sandbox Code Playgroud)