Oracle의 BAND 변수를 통해 열 이름을 참조 할 수 있습니까?
-
03-07-2019 - |
문제
Oracle 데이터베이스와 통신하는 응용 프로그램에서 쿼리를 주문하기 위해 열 이름을 참조하려고합니다. 쿼리를 주문할 내용을 동적으로 변경할 수 있도록 바인드 변수를 사용하고 싶습니다.
내가 가진 문제는 데이터베이스가 열별로 순서를 무시하는 것 같습니다.
바인드 변수를 통해 데이터베이스 열을 참조하는 특정 방법이 있는지 또는 가능한지 아는 사람이 있습니까?
예를 들어 내 쿼리입니다
SELECT * FROM PERSON ORDER BY :1
(어디 :1
묶여 있습니다 PERSON.NAME
) 쿼리는 알파벳 순서로 결과를 반환하지 않습니다. 데이터베이스가 이것을 다음과 같이 해석하고 있다고 걱정합니다.
SELECT * FROM PERSON ORDER BY 'PERSON.NAME'
분명히 작동하지 않을 것입니다.
모든 제안은 대단히 감사합니다.
해결책
아니요. 테이블 또는 열 이름에 바인드 변수를 사용할 수 없습니다.
이 정보는 실행 계획을 작성하기 위해 필요합니다. 주문하고 싶은 것이 무엇인지 알지 못하면 예를 들어 어떤 색인을 사용해야하는지 알아내는 것은 불가능합니다.
바인딩 변수 대신 프로그램이 생성 할 때 열 이름을 SQL 문에 직접 보간해야합니다. SQL 주입에 대해 예방 조치를 취한다고 가정하면 그에 대한 하락은 없습니다.
업데이트: 정말로 후프를 뛰어 넘고 싶었다면 아마도
order by decode(?, 'colA', colA, 'colB', colB)
그러나 그것은 단지 바보입니다. 그리고 느린. 하지 않다.
다른 팁
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);
resultSet result = select.executeQuery ( "select * from pers order by"+columnName);
항상 데이터베이스에 대한 새로운 진술이 될 것입니다. 즉, Thilo가 이미 설명한 것처럼 이미 구속, 계산, 준비, 구문 분석 된 진술을 "재주문"하는 것은 불가능하다는 것을 의미합니다. 응용 프로그램 에서이 결과를 계속해서 사용하고 시간이 지남에 따라 변경되는 유일한 것은 프레젠테이션 순서입니다. 클라이언트 코드에서 세트를 주문하십시오. 그렇지 않으면 Dynamic SQL은 괜찮지 만 발자국이 있습니다.