ORA-00907: отсутствует правая скобка с PreparedStatement

Я пытаюсь выполнить этот запрос, но у меня есть ошибка

ORA-00907: отсутствует правая скобка

Я рассмотрел заявление, но скобки правы. Я удалил последнюю строку запроса, и она работает:

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

возможно, что-то может быть в операторе '>', но я не могу сделать это без этого.

Код:

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;
    }
}

Поэтому в другом методе я заполняю некоторые циклы for, потому что в некоторых случаях параметры (которые находятся в файле свойств) могут быть более одного.

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

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

3 ответа

Решение

INTERVAL ? MINUTE не является действительным.

Синтаксис INTERVAL '1' MINUTE (и вы не можете указать переменную для значения).

Если вы хотите указать переменную, вам нужно использовать TO_DSINTERVAL()

Что-то вроде:

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

В сторону

Вы, кажется, передаете списки в запрос, изменяя запрос так, чтобы он принимал несколько переменных связывания; тебе не нужно этого делать. Вместо этого вы можете передать коллекцию Oracle как одну переменную связывания. Пример этого можно найти здесь (немного сложнее, как этот пример для многомерных массивов), но здесь есть более простой пример.

Конечное условие WHERE Предложение в подзапросе должно выглядеть примерно так:

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

Вы должны поместить количество времени в одинарные кавычки.

Более простое решение, использующее interval или же to_dsinterval() это использовать прямую дату арифметики. Вы можете добавлять или вычитать числа в / из даты или времени; число выражается в днях, поэтому, если ваш ввод (показанный как?) указан в минутах, вы должны разделить его на 24*60. Вот так:

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

Обратите внимание, что это изменит правую часть на дату / время (без долей секунды), поэтому не будет работать, если вам нужны доли секунды.

Другие вопросы по тегам