2009-03-04 2 views
3

Oracle 데이터베이스와 통신하는 응용 프로그램에서 쿼리를 정렬하려면 열 이름을 참조하려고합니다. 바인드 변수를 사용하여 쿼리 순서를 동적으로 바꿀 수 있습니다.Oracle에서 바인드 변수를 통해 열 이름을 참조 할 수 있습니까?

내가 겪고있는 문제는 데이터베이스가 열을 기준으로 주문을 무시하는 것 같습니다.

바인드 변수를 통해 데이터베이스 열을 참조하는 특별한 방법이 있는지 또는 가능한지 알고있는 사람이 있습니까?

예를 들어 내 쿼리가 알파벳 순서로 쿼리는 반환하지 않습니다 결과를 (:1PERSON.NAME에 바인딩됩니다)

SELECT * FROM PERSON ORDER BY :1 

, 나는 데이터베이스로이 해석되는 것을 걱정 : -

SELECT * FROM PERSON ORDER BY 'PERSON.NAME' 

분명히 작동하지 않습니다.

모든 의견을 보내 주시면 감사하겠습니다.

답변

6

아니요. 테이블 또는 열 이름에 대해 바인드 변수를 사용할 수 없습니다.

이 정보는 실행 계획을 작성하는 데 필요합니다. 주문하고자하는 것을 알지 못하면 사용할 색인을 알아낼 수 없습니다.

바인드 변수 대신 프로그램이 SQL 문을 작성할 때 직접 열 이름을 보간해야합니다. SQL 인젝션에 대해주의를 기울인다 고 가정하면, 거기에는 단점이 없습니다.

업데이트 : 당신이 정말 농구를 통해 이동하고 싶다면, 당신은 아마

order by decode(?, 'colA', colA, 'colB', colB) 

처럼 뭔가를 할 수 있지만, 그건 그냥 바보입니다. 그리고 천천히. 하지마.

+0

+1 btw 오라클의 경우 맞는지는 모르겠지만 DB2와 같은 다른 데이터베이스에는 분명히 단점이 있습니다. 쿼리 명령 텍스트를 수정하면 데이터베이스를 캐시하는 것이 훨씬 어려워집니다. 시간 (그리고 매개 변수의 값뿐만 아니라) –

+0

그것은 오라클에서도 발생합니다. 그러나 명령 텍스트를 항상 변경하지는 않습니다.열 이름에는 몇 가지 선택 사항 만 있으므로 5 개의 캐시 항목 만 있습니다. – Thilo

+0

고마워, 나에게 의미가있다. 나는 order by 절을 볼 때 코드를 이해하도록 노력할 것이고, 거기에 바인드 변수가 있으면 그 값으로 대체 할 것이다. – Scottm

2

JDBC를 사용 중입니다. 바인드 변수를 사용하지 않고 코드를 다시 작성할 수 있습니다. 당신은 또한 동적 예컨대 :

String query = "SELECT * FROM PERS "; 
    if (condition1){ 
     query = query+ " order by name "; 
    // insert more if/else or case statements 
    } else { 
     query = query+ " order by other_column "; 
    } 
    Statement select = conn.createStatement(); 
    ResultSet result = select.executeQuery(query); 

심지어

String columnName = getColumnName(input); 
    Statement select = conn.createStatement(); 
    ResultSet result = select.executeQuery("SELECT * FROM PERS ORDER BY "+columnName); 
+0

데이터베이스는 SQL을 사용하는 것이 가장 좋습니다. –

+0

나는 동의하지 않는다 - 이것은 좋은 제안이다, Edwin, 고마워. 나는 이런 식으로해야 할 것처럼 보입니다. 또한 열을 기준으로 주문을 추가 할 때 쿼리 문자열에서 자리 표시 자 제거를 수행해야합니다. – Scottm

0

의 ResultSet 결과 = select.executeQuery에 의해 순서 - 더를 변경할 수 있습니다이 방법은 (+ COLUMNNAME "에 의해 PERS의 ORDER SELECT * FROM");

은 항상 데이터베이스에 대한 NEW 문입니다. 이미 Thilo가 설명했듯이, 이미 바인딩 된, 계산 된, 준비된, 파싱 된 문장을 "재정렬"하는 것은 불가능하다는 것을 의미합니다. 응용 프로그램에서이 결과 세트를 계속 사용할 때 시간이 지남에 따라 변경되는 것은 프레젠테이션 순서 뿐이지 만 클라이언트 코드에서 집합을 정렬하십시오. 그렇지 않으면 동적 SQL은 좋지만 엄청난 공간을 차지합니다.

+0

columnName이 * always * different 인 경우에만 새 명령문이됩니다. 나는 columnName이 값의 작은 집합 중 하나를 취하는 것을 기대한다. 이것은 공유 풀에 대한 손실이 최소화된다는 것을 의미한다. –

관련 문제