독트린 2를 사용하여 테이블을 자르는 방법?
나는 Doctine2를 사용하여 테이블을 잘라내기 위해 네이티브 쿼리를 구축해야 한다고 생각합니다.
$emptyRsm = new \Doctrine\ORM\Query\ResultSetMapping();
$sql = 'TRUNCATE TABLE Article';
$query = em()->createNativeQuery($sql, $emptyRsm);
$query->execute();
그러면 오류가 발생합니다.
SQLSTATE[HY000]: General error
이것을 작동시키려면 내 코드를 무엇으로 바꿔야 합니까?
테이블 자르기 주의
특히 커밋/롤백 기능을 위해 명시적 트랜잭션을 사용하려는 경우 RDBMS에서 테이블을 잘라내지 않도록 주의해야 합니다.이 답변의 '나의 추천'을 읽어보세요.
DDL 문은 암시적 커밋을 수행합니다.
잘라내기 테이블 문은 DDL(Data Definition Language) 문이므로, 잘라내기 테이블 문은 실행 시 데이터베이스에 암시적인 영향을 미칩니다.만약 당신이 공연을 한다면.TABLE TRUNCATE
그러면 데이터베이스는 암묵적으로 에 전념합니다.TABLE TRUNCATE
A 이내에 있습니다.START TRANSACTION
statement--당신의 테이블은 잘리고 a.ROLLBACK
복구하지 못할 겁니다
잘라내기 테이블 문은 암묵적 커밋을 수행하기 때문에 Maxence의 대답이 예상대로 수행되지 않습니다(그러나 잘못된 것은 아닙니다. 왜냐하면 질문은 "테이블 잘라내기 방법"이었기 때문입니다).그의 대답은 테이블을 a로 잘라 버리기 때문에 예상대로 수행되지 않습니다.try
블록, 및 테이블이 복원될 수 있다고 가정합니다.catch
무슨 일이 생기면 차단합니다.이는 잘못된 가정입니다.
이 스레드에서 다른 사용자의 의견 및 경험
잘라내기 테이블 문이 명시적 트랜잭션에 있더라도 잘라내기 테이블 문을 롤백할 수 없기 때문에 Chris Aelbrecht가 Maxence의 솔루션이 제대로 작동하도록 할 수 없습니다.
user2130519는 유감스럽게도 정답을 제시했다는 이유로 (-1을 찬성하기 전까지) 반대표를 받았습니다. 이는 그가 자신의 답을 정당화하지 않고 그렇게 했음에도 불구하고, 이는 여러분의 작업을 보여주지 않고 수학을 하는 것과 같습니다.
나의 추천.DELETE FROM
제가 추천하는 것은DELETE FROM
. 대부분의 경우 개발자가 기대하는 대로 작동합니다.그렇지만,DELETE FROM
테이블에 대한 자동 증분 값을 명시적으로 재설정해야 합니다.테이블의 자동 증분 값을 재설정하려면 다른 DDL 문을 사용해야 합니다.ALTER TABLE
--그리고, 다시 말하지만, 사용하지 마.ALTER TABLE
당신의try
블록입니다. 생각대로 되지 않습니다.
언제 사용해야 하는지에 대한 팁을 원하시면DELETE FROM
대TRUNCATE
TRUNCATE 대 DELETE FROM의 장단점을 참조하십시오.
꼭 필요한 경우 자르는 방법은 다음과 같습니다.
자, 그런 말을 다 했으니 말입니다.Doctrine2를 사용하여 테이블을 자를려면 다음을 사용합니다. (아래는 Maxence의 답변에서 테이블을 올바르게 자르는 부분입니다.)
$cmd = $em->getClassMetadata($className);
$connection = $em->getConnection();
$dbPlatform = $connection->getDatabasePlatform();
$connection->query('SET FOREIGN_KEY_CHECKS=0');
$q = $dbPlatform->getTruncateTableSql($cmd->getTableName());
$connection->executeUpdate($q);
$connection->query('SET FOREIGN_KEY_CHECKS=1');
롤백/커밋 기능이 있는 테이블을 삭제하는 방법.
그러나 롤백/커밋 기능을 사용하려면 다음을 사용해야 합니다.DELETE FROM
: (아래는 Maxence의 답변을 수정한 것입니다.)
$cmd = $em->getClassMetadata($className);
$connection = $em->getConnection();
$connection->beginTransaction();
try {
$connection->query('SET FOREIGN_KEY_CHECKS=0');
$connection->query('DELETE FROM '.$cmd->getTableName());
// Beware of ALTER TABLE here--it's another DDL statement and will cause
// an implicit commit.
$connection->query('SET FOREIGN_KEY_CHECKS=1');
$connection->commit();
} catch (\Exception $e) {
$connection->rollback();
}
자동 증분 값을 재설정해야 할 경우 다음을 참조하십시오.ALTER TABLE <tableName> AUTO_INCREMENT = 1
.
제가 사용하고 있는 코드는 다음과 같습니다.
$cmd = $em->getClassMetadata($className);
$connection = $em->getConnection();
$dbPlatform = $connection->getDatabasePlatform();
$connection->beginTransaction();
try {
$connection->query('SET FOREIGN_KEY_CHECKS=0');
$q = $dbPlatform->getTruncateTableSql($cmd->getTableName());
$connection->executeUpdate($q);
$connection->query('SET FOREIGN_KEY_CHECKS=1');
$connection->commit();
}
catch (\Exception $e) {
$connection->rollback();
}
아니면 그냥 이걸 시도해 보셔도 됩니다.
$this->getEm()->createQuery('DELETE AcmeBundle:Post p')->execute();
관계가 있는 경우 연결된 엔티티를 처리하는 데 주의해야 합니다.
단위 검정에서 특성을 잘라내는 방법의 예제입니다.
/**
* Cleanup any needed table abroad TRUNCATE SQL function
*
* @param string $className (example: App\Entity\User)
* @param EntityManager $em
* @return bool
*/
private function truncateTable (string $className, EntityManager $em): bool {
$cmd = $em->getClassMetadata($className);
$connection = $em->getConnection();
$connection->beginTransaction();
try {
$connection->query('SET FOREIGN_KEY_CHECKS=0');
$connection->query('TRUNCATE TABLE '.$cmd->getTableName());
$connection->query('SET FOREIGN_KEY_CHECKS=1');
$connection->commit();
$em->flush();
} catch (\Exception $e) {
try {
fwrite(STDERR, print_r('Can\'t truncate table ' . $cmd->getTableName() . '. Reason: ' . $e->getMessage(), TRUE));
$connection->rollback();
return false;
} catch (ConnectionException $connectionException) {
fwrite(STDERR, print_r('Can\'t rollback truncating table ' . $cmd->getTableName() . '. Reason: ' . $connectionException->getMessage(), TRUE));
return false;
}
}
return true;
}
만약 당신이 사용하지 않을 경우$em->flush()
, 교의 다음 질의에 문제가 있을 위험이 있습니다.
또한 컨트롤러에서 이 방법을 사용할 경우 라인을 변경해야 함을 이해해야 합니다.fwrite(STDERR, print_r(...
당신의 로거 서비스가 사용할 수 있는 무언가에.
이것은 교의(외부 키 검사를 무시하지 않음)를 사용하여 기호의 엔티티 리포지토리에서 모든 엔터티를 삭제할 수 있는 방법입니다.함수는 삭제된 엔터티 개수를 반환합니다.
/**
* @return int
*/
public function deleteAll(): int
{
$qb = $this->createQueryBuilder('t');
$qb->delete();
return $qb->getQuery()->getSingleScalarResult() ?? 0;
}
언급URL : https://stackoverflow.com/questions/9686888/how-to-truncate-a-table-using-doctrine-2
'programing' 카테고리의 다른 글
C++의 NULL이 일반적으로 C와 같은 포인터가 아닌 정수 리터럴인 이유는 무엇입니까? (0) | 2023.11.05 |
---|---|
array_intergect의 반대? (0) | 2023.11.05 |
ES6/7에서 Arrow 기능을 내보낼 수 있습니까? (0) | 2023.11.05 |
자식 요소를 끌 때 부모 요소 화재의 'drag 이탈' (0) | 2023.11.05 |
"디스플레이: 테이블 셀;"이 있는 디브가 마진의 영향을 받지 않는 이유는 무엇입니까? (0) | 2023.11.05 |