2016-06-27 10 views
0

내가이 쿼리를 실행하기 위해 노력하고있어와 오른쪽 괄호 누락,하지만 난 오류를ORA-00907 : PreparedStatement의

ORA-00907를 가지고 :없는 오른쪽 괄호

내가 검토 문이 있지만 괄호가 옳다. 나는 쿼리의 마지막 줄을 제거하고 그것을 작동 :

AND TN.LAST_UPDATEDATE > (CURRENT_TIMESTAMP - INTERVAL ? MINUTE) 

어쩌면 '>'oparator에 뭔가 할 수 있습니다,하지만 난 그것을 whithout이 작업을 수행 할 수 없습니다.

코드 : 매개 변수 바인딩

String sql= "SELECT DID.ORDER_ID " 
      + "FROM TEST_ORDER DID, TEST_ORDER_SG DOS, TEST_HRD_SHIPS_GRP DHSG, TEST_INFO CSI " 
      + "WHERE DID.ORDER_ID = DOS.ORDER_ID " 
      + "AND DOS.SHIPPING_GROUPS = DHSG.SHIPPING_ID " 
      + "AND DOS.SHIPPING_GROUPS = CSI.SHIPPING_ID " 
      + "AND DHSG.TRACKING_CODE IS NULL AND CSI.SHIPPING_CARRIER IN " 
      + "(?) " 
      + "AND DID.STATE IN (?) " 
      + "AND NOT EXISTS " 
      + "(" 
      + "SELECT 1 FROM " 
      + "CLIENT_INTEGRATION.TEST_LOG_ORDERS_STATUS TN " 
      + "WHERE TN.ORDER_ID = DID.ORDER_ID AND TN.STATE = DID.STATE " 
      + "AND TN.LAST_UPDATEDATE > (CURRENT_TIMESTAMP - INTERVAL ? MINUTE)" 
      + ")"; 

코드 : 나는 루프에 대한 몇 가지 채우기 다른 방법에 따라서

int actualIndex = 0; 
for (int i = 0; i < params.length; i++) { 
    actualIndex = sql.indexOf('?', actualIndex+1); 
    Class classe = params[i].getClass(); 

    if(classe.isArray()) { 
     StringBuffer newPlaceHolders = new StringBuffer(); 

     int arrayLength = java.lang.reflect.Array.getLength(params[i]); 

     for (int j = 0; j < arrayLength; j++) { 

      if (j>0) { 
       newPlaceHolders.append(",?");       
      } else { 
       newPlaceHolders.append("?");       
      } 
     } 

     sql = sql.substring(0, actualIndex) + newPlaceHolders + sql.substring(actualIndex+1); 
     actualIndex += newPlaceHolders.length(); 
    } 

    if (actualIndex == -1) { 
      break; 
    } 
} 

을, 어떤 경우에는 원인, 등록 정보에있는 매개 변수 (파일)은 둘 이상일 수 있습니다.

int i=1; 
    for(String carriers : getCarrier()) { 
     ps.setString(i, carriers);    
     i++; 
    } 

    for(String state : getAllStates()) { 
     ps.setString(i, state); 
     i++; 
    } 

답변

0

INTERVAL ? MINUTE은 유효하지 않습니다.

구문은 INTERVAL '1' MINUTE이며 값에 대한 변수를 지정할 수 없습니다.

당신은 당신이 같은 TO_DSINTERVAL()

뭔가 사용할 필요가 변수 지정하려면 :

TO_DSINTERVAL('0 00:' || TO_CHAR(?, 'FM00') || ':00') 

을 제외하고

당신은을 수정하여 쿼리에 목록을 통과 한 것으로 나타났습니다 쿼리는 여러 바인드 변수를 사용합니다. 당신은 이것을 할 필요가 없습니다. 대신 오라클 콜렉션을 단일 바인드 변수로 전달할 수 있습니다. 예를 들어 here (그 예가 다차원 배열 인 경우 약간 더 복잡함)이지만 더 간단한 예제 here이 있습니다.

0

서브 쿼리에서 WHERE 조항의 최종 조건은 다음과 비슷한 모습이 될 것

AND TN.LAST_UPDATEDATE > (CURRENT_TIMESTAMP - INTERVAL '10' MINUTE) 

당신은 작은 따옴표로 시간의 양을 배치해야합니다.

0

interval 또는 to_dsinterval()을 사용하는 간단한 해결책은 직접 날짜 산술을 사용하는 것입니다. datetime 또는 timestamp에 숫자를 추가하거나 뺄 수 있습니다. 숫자는 일 단위로 표시되므로 입력 사항 (?으로 표시)이 분 단위 인 경우 24 * 60으로 나누어야합니다. 그래서 같이 :

... and tn.last_update > current_timestamp - ?/24 * 60 

이 날짜/시간에 오른쪽 (NO 분수 초)을 변경 않습니다, 그래서 당신은 두 번째의 분수를 필요로하는 경우 작동하지 않습니다하시기 바랍니다.