PDO 준비 문에서 어떤 토큰을 매개변수화할 수 있나요?
-
06-07-2019 - |
문제
저는 PHP/PDO에서 준비된 명령문을 가지고 놀고 있습니다.기본 쿼리는 WHERE 절에 값을 전달하여 제대로 작동합니다.
$stmt = $db->prepare( 'SELECT title FROM episode WHERE id=:id' );
$stmt->bindParam( ':id', $id, PDO::PARAM_INT );
$id = 5;
$stmt->execute();
그러나 필드 이름에 대한 변수를 전달해야 하는 상황이 있습니다.다음 쿼리(적절한 바인딩 포함)는 제대로 작동합니다.
SELECT :field FROM episode WHERE id=:id
이것은 오류를 발생시킵니다:
SELECT title FROM :field WHERE id=:id
이것은 오류를 발생시키지 않지만 행을 반환하지 않습니다.
SELECT title FROM episode WHERE :field=:id
그렇다면 준비된 진술에서는 어떤 것들이 작동해야 할까요?필드 이름, 테이블 이름 등을 '매개변수화'할 수 있습니까?
해결책
테이블 이름, 열 이름 또는 IN
절 (C0R0ner에게 감사합니다 지적 IN
조항 제한).
보다 이 질문, 그리고 그 후 PHP 매뉴얼에있는이 의견.
다른 팁
@ 조쉬 라이첼
이러한 생각은 특히 데이터베이스에 표현된 동적 트리 구조의 경우 매우 제한적입니다(제 생각에는 강력한 솔루션을 구현하기에는 너무 게으른 것에 대한 변명일 뿐입니다).
다음 예를 고려하십시오.
내 프로젝트에는 논리적 구조가 있습니다.
회사 계층 구조는 엔터티 측면에서 표현됩니다.각 엔터티는 일반적인 경우 계층 구조의 구성원이거나 계층 구조의 특정 수준의 구성원으로 처리될 수 있습니다.계층 구조 자체는 테이블에서 다음과 같이 단일 트리 분기로 정의됩니다.
entity_structure (
id
name
parent_entity_structure_id
);
엔터티 자체는 다음과 같이 표현됩니다.
entities (
id
name
entity_structure_id
parent_id
);
사용 편의성을 위해 트리의 평면 보기를 생성하는 알고리즘을 구축했습니다.다음 구체적인 예는 제가 의미하는 바를 보여줍니다.
SELECT * FROM entity_structure;
id | name | entity_structure_parent_id
-----------------------------------------------------------
1 | Company | null (special one that always exists)
2 | Division | 1
3 | Area | 2
4 | Store | 3
이로 인해 다음과 같은 평면 표현이 생성됩니다.
entity_tree (
entity_id
division_id
area_id
store_id
)
분할 수준에 있는 엔터티는 Division_id, Area_id 및 store_id를 NULL로, 영역 Area_id 및 store_id를 NULL로 갖습니다.
이것의 좋은 점은 다음과 유사한 명령문을 사용하여 디비전의 모든 하위 항목을 쿼리할 수 있다는 것입니다.
SELECT * FROM entity_tree WHERE division_id = :division_id;
그러나 이는 내가 쿼리하는 엔터티의 구조 수준을 알고 있다고 가정합니다.다음을 수행하는 것이 좋을 것입니다.
SELECT * FROM entity_tree WHERE :structure = :entity_id;
단일 엔터티의 구조 수준을 파악하는 것이 어렵지 않다는 것을 알고 있지만 모두 동일한 수준에 있지 않을 수 있는 엔터티 컬렉션을 반복한다고 가정합니다.지금은 계층의 각 수준에 대해 별도의 쿼리를 작성해야 하지만 필드를 매개변수화할 수 있다면 다음을 수행할 수 있습니다.
$children = array();
$stmt = $pdo->prepare('SELECT entity_id FROM entity_tree WHERE :structure = :entityId');
foreach ($entities AS $entity) {
$stmt->execute(array(
':structure' = $entity->getEntityStructureId(),
':entityId' = $entity->getId()
));
$children[$entity->getId()] = $stmt->fetchAll(PDO::FETCH_COLUMN);
}
결과적으로 더 깔끔한 코드와 단 하나의 준비된 문만 생성됩니다.
전체 예제에서는 사용자 입력이 전혀 사용되지 않습니다.
고려해야 할 사항입니다.
당신은 내부에 아무것도 매개 변수화 할 수 없습니다 IN
조항도.