2013-07-10 3 views
3

내 테이블에서 Person 개체는 다른 사람과 관계를 가질 수 있습니다. 저는 인간의 관계, 관계의 관계 등등을 되 돌리는 재귀 적 절차를 만들고 싶습니다.SQL을 사용하여 재귀 호출을 작성하려면 어떻게합니까?

두 개의 열, PersonPersonRelation이있는 테이블이 있습니다. 내 PersonBeanImpl에서

PERSON   PERSON_RELATION 
id    id 
name   person_id 
age   relation_id 
       relation_type   

나는 Person's 관계도의 관계 등 (recusrivly)의 목록을 반환하는 방법이 있습니다

public List<Person> getPersonRelationsAndTheirRelations(int personId) { 
    List<Person> relations = new ArrayList<>(); 
    getRelationsRecursivly(relations, personId); 
    return relations; 

} 
private void getRelationsRecursivly(List<Person> relations, int personId) { 
    relations.addAll(fetchPersonRelation(personId)); 
    for(Person p : relations){ 
     getRelationsRecursivly(relations, p.getId()); 
    } 
} 

public List<Person> fetchPersonRelation(int personId) { 
    String sql = "SELECT p FROM Person p, PersonRelation pr WHERE pr.relationId = p.Id AND pr.personId = :personId"; 
    Query query = entityManager.createQuery(sql); 
    query.setParameter(":personId", personId); 
    return query.getResultList(); 
} 

이 코드는 작동하지만 거대한 소요 fetchPersonRelation() 메서드가 여러 번 호출 된 이후로 트랜잭션을 완료하는 데 걸리는 시간.

SQL을 사용하여 모든 것을 재귀 적으로 수행 할 수 있습니까? PostgreSQL을 사용하고 있습니다.

SQLFiddle 예 : http://sqlfiddle.com/#!12/c1f32/3

+0

예 : for 루프, while 루프 및 커서를 sql에 사용할 수 있습니다. –

+0

이것은 SQL에서는 불가능합니다. 가장 좋은 방법은'JOIN'을 사용하여 단일 쿼리의 모든 데이터를 검색하고 연관시켜야하는 값으로 정렬 한 다음 Java 코드에서 수동으로 처리하는 것입니다. 최소 10 배 이상 빠릅니다. –

+0

@ShreyosAdikari SQL에 대한 서버 별 추가 (예 : PLPGSQL/Transact-SQL)에서 사용할 수 있지만 ANSI SQL 표준의 일부는 아닙니다. –

답변

1

당신은 recursive common table expressions로 할 수 있습니다. 하지만 그들은 조금 까다 롭기 때문에 무한 루프가 발생하지 않도록해야합니다. 그러나 큰 데이터베이스의 경우 모든 레코드를 꺼내야 함을 기억하십시오 (Six degrees of seperation).

+0

답변 해 주셔서 감사합니다! 나는 SQL에서 WITH RECURSIVE 문에 익숙하지 않다. 현재 SQL 문에서 마지막 SQL 문으로 검색 한'personId'를 어떻게 사용합니까 (위 코드 에서처럼 재귀 적으로 만드십시오)? – Rox