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


102

Doctrine 2를 사용하여 원시 SQL을 실행하고 싶습니다.

데이터베이스 테이블을 자르고 기본 테스트 데이터로 테이블을 초기화해야합니다.


2
그건 그렇고, mysqldumps를 수행 하거나 이전 덤프에서 데이터를로드하거나 테이블을 삭제 하는 것과 같은 자동화 된 데이터베이스 지저분한 작업을 수행하려면 일반적으로 해당 작업에 대한 셸 스크립트를 작성한 다음 Symfony2 언어로 작업 (또는 "명령")을 작성합니다. ) 쉘 스크립트를 실행합니다. 내가 아는 한 ORM의 목적은 반복적 인 작업을 추상화하는 것입니다. 그리고 만약 당신이 테이블을 자르는 것과 같은 일을한다면, Doctrine이 그림에 포함되지 않았기 때문에 어떻게 이해가 될지 모르겠습니다. 그 작업을 더 쉽게 만듭니다.
Jason Swett

답변:


164

다음은 제가하고있는 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();
}   

4
좋은 대답입니다. 이 코드에서 엔티티 관리자를 가져 오려면 "$ this-> getEntityManager ()" 위의이 코드 대신 $ this-> getDoctrine ()-> getManager () 를 사용할 수 있습니다 . 이렇게하면 즉시 작동합니다.
webblover 2014-08-22

헤이는 나에게 내가 무엇을해야하는지 정의되지 않은 메서드 지수 :: getDoctrine ()로 전화 제공
덱스터

교리 2 CodeIgniter의를 사용하여 메신저 wildlyinaccurate.com/integrating-doctrine-2-with-codeigniter-2
덱스터

1
이것은 나를 올바른 방향으로 이끌었지만 정확히 필요한 것이 아닙니다. 나는 대답의 나이가 차이를 만든다고 생각합니다. 나는 사용 : ...getConnection()->query($sql);그리고 실행할 필요가 없었습니다$stmt->execute();
Brandon

Symfony4 및 autowiring을 사용하면 힌트를 입력 EntityManagerInterface $entityManager한 다음 전화를 걸 수 있습니다.$entityManager->getConnection()
COil

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

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

18
또한 exec 대신 prepare ()를 호출하여 준비된 명령문 지원을 계속받을 수 있습니다.
Jeremy Hicks

44

나는 당신이 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을 변경할 수 있습니다.


1
그들 중 가장 좋은 예
David

14

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

관리자와 연결하고 새로운 연결을 만드십시오.

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

1
query ()는 SQL이 사용하려는 데이터를 반환하는 경우입니다. 간부 () 그렇지 않은 경우입니다
Jeffiekins

12

나는 대답이 아마도 다음과 같다는 것을 알았습니다.

NativeQuery를 사용하면 기본 SQL을 실행하여 사양에 따라 결과를 매핑 할 수 있습니다. SQL 결과 집합이 Doctrine 결과에 매핑되는 방법을 설명하는 이러한 사양은 ResultSetMapping으로 표시됩니다.

출처 : Native SQL .


17
이것은 받아 들여지는 대답이지만 항상 ResultSetMapping이 필요하기 때문에 Doctrine 의이 부분이 어떻게 유용한 지 알 수 없습니다. 나는 그것이 임의의 SQL을 실행하는 지점을 기본값으로하는 엔티티에 결과를 매핑하는 것을 원하지 않는다!
MikeMurko 2011

2
@MikeMurko 나는 교리 2 원시 쿼리를 실행하기위한이 게시물에 도움이 발견 : forum.symfony-project.org/viewtopic.php?f=23&t=37872
제이슨 Swett에게

또한 네이티브 SQL은 가능한 모든 SQL 쿼리를 실행하지 않습니다. DELETE / UPDATE / INSERT는 작동하지 않으며 교리 가정을 따르지 않는 일부 테이블 정의도 작동하지 않습니다. (ID가없는 M2M 조인 테이블). 따라서이 대답은 보편적이지 않습니다. INSERT가 작동하지 않기 때문에 허용되어서는 안됩니다.
przemo_li 2015


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

4

그럴 수 없습니다. 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 비즈니스에 맡기는 것도 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.