programing

원칙 2를 사용하여 원시 SQL 실행

javaba 2023. 1. 29. 20:35
반응형

원칙 2를 사용하여 원시 SQL 실행

원칙 2를 사용하여 raw 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을 변경할 수 있습니다.

원시 쿼리를 실행하고 데이터를 반환하는 방법.

매니저에게 접속하여 새로운 접속을 확립합니다.

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

제가 알아낸 답은 아마 다음과 같습니다.

NativeQuery를 사용하면 기본 SQL을 실행하여 사양에 따라 결과를 연결할 수 있습니다.SQL 결과 세트가 교리 결과에 매핑되는 방법을 설명하는 이러한 사양은 ResultSetMapping으로 나타납니다.

출처: 네이티브 SQL.

대부분의 답변은 현재 독트린 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

따라서 raw 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;
}   

저도 같은 문제가 있었어요.엔티티 관리자가 제공한 연결 개체를 확인합니다.

$conn = $em->getConnection();

그런 다음 이에 대해 직접 쿼리/실행할 수 있습니다.

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

connection 객체에 대한 문서는http://http://www.doctrine-project.org/api/dbal/2.0/doctrine/dbal/connection.html 에서 참조해 주세요.

모델 내에서 raw 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();

그럴 수 없어요, 원칙 2는 원시 쿼리를 허용하지 않습니다.할 수 있는 것처럼 보이지만, 다음과 같은 것을 시도하면:

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

DATE_FORMAT이 알 수 없는 함수임을 나타내는 오류가 발생합니다.

그러나 내 데이터베이스(MySQL)는 그 함수를 알고 있기 때문에 기본적으로는 Query가 백그라운드에서 (그리고 당신의 뒤에서) 해석하고 Query가 유효하지 않다고 간주하여 이해하지 못하는 표현을 찾는 것입니다.

따라서 저처럼 데이터베이스에 문자열을 전송하여 처리(및 보안에 대한 모든 책임은 개발자가 지게 함)할 수 있도록 하고 싶은 경우에는 이 문제를 해결하지 마십시오.

물론 어떤 식으로든 그것을 허용하기 위해 확장을 코드화할 수 있지만, mysqli를 사용하여 이를 수행하고 독트린을 ORM 비즈니스에 맡기는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/3325012/execute-raw-sql-using-doctrine-2

반응형