2015-12-15 3 views
1

Я видел примеры здесь и в других местах, которые говорят, что это должно работать.
с параметром «1» в ПУНКТЕ В меня есть успех:Подготовленные утверждения IN clause Java Microsoft JDBC

SELECT AVG((High_Temperature + Low_Temperature)/2.0) 
    FROM obs_masterAll 
    WHERE Observation_Valid_Time = ? AND 
     Location_ID IN (?); 

Microsoft JDBC Driver 4.2 for SQL Server 4.2.6420.100 
Parameter Count = 2 
2010, 36.5 

Но, с более чем одним параметром в ПУНКТЕ, я получаю это:

SELECT AVG((High_Temperature + Low_Temperature)/2.0) 
    FROM obs_masterAll 
    WHERE Observation_Valid_Time = ? 
    AND Location_ID IN (?, ?);  <--- PROBLEM HERE 

Microsoft JDBC Driver 4.2 for SQL Server 4.2.6420.100 
Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near ','. 
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:191) 
    at com.microsoft.sqlserver.jdbc.SQLServerParameterMetaData.<init>(SQLServerParameterMetaData.java:423) 
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.getParameterMetaData(SQLServerPreparedStatement.java:1659) 
    at CreateAMultiStationDailyLoadCtrAvgHistogram.main(CreateAMultiStationDailyLoadCtrAvgHistogram.java:68) 
Java Result: 1 

Вот мой код:

prepStmt = buildPreparedStatement(conn.getConnectionObject()); //function below 
    conn.printDriverInfo(); 
    sqlDate = new java.sql.Date(beginDate.getTimeInMillis()); 
    ParameterMetaData pmData = prepStmt.getParameterMetaData(); 
    System.out.println("Parameter Count = " + pmData.getParameterCount()); 
    prepStmt.setDate(1, sqlDate); 

    for(i = 0; i < locID.size(); i++) 
    { 
    prepStmt.setString((i + 2), locID.get(i)); 
    } 

    rslt = prepStmt.executeQuery(); 

    private PreparedStatement buildPreparedStatement(java.sql.Connection con) 
    throws SQLException 
    { 
    int i; 
    StringBuilder sb = new StringBuilder(); 
    sb.append("SELECT AVG((High_Temperature + Low_Temperature)/2.0) "); 
    sb.append("FROM obs_masterAll "); 
    sb.append("WHERE Observation_Valid_Time = ? AND "); 
    sb.append("Location_ID IN ("); 

    for(i = 0; i < (locID.size() - 1); i++) 
    { 
     sb.append("?").append(", "); 
    } 

    sb.append("?").append(");"); 
    System.out.println(sb.toString()); 
    return(con.prepareStatement(sb.toString())); 
    } 

Является ли проблема моим кодом или драйвером JDBC?

+0

Вы неправильно присваиваете значения заполнителям. Вы написали i

+0

«Гость» -> Большое спасибо за быстрый ответ! Я считаю, что проблема связана с синтаксисом SQL (в первой строке трассировки стека выше). Ошибка кода при создании объекта ParameterMetaData и даже не позволяет присвоить параметры. – TheStressMan

ответ

0

Ответ, приведенный выше относительно драйвера JDBC, заставил меня закрыть. Я использовал очень старый драйвер Microsoft JDBC, поэтому обновление, безусловно, помогло. Теперь я использую версию предварительного просмотра сообщества версии 6.0 драйвера Microsoft JDBC (версия 6.0.6629.101), как было рекомендовано выше.

Однако у меня все еще возникали проблемы.

Когда я удалил следующую строку (ы) из кода:

ParameterMetaData pmData = prepStmt.getParameterMetaData(); 
System.out.println("Parameter Count = " + pmData.getParameterCount()); 

Все работает, как ожидалось!

Я не уверен, почему тип данных ParameterMetaData не работает, но когда он удаляется из кода, он определенно разрешил мои проблемы.

Исправлено!

2

Я бы сказал, что это проблема в версии используемого драйвера JDBC.

Я мог бы воспроизвести эту проблему, используя ту же версию драйвера JDBC SQL Server, что и вы. Я не мог воспроизвести эту проблему с тем же запросом, что и MySQL, или Oracle. Мне пришлось удалить точку с запятой с конца запроса, чтобы она запускалась против Oracle, но это же изменение не устраняет ситуации для SQL Server.

Я также не смог воспроизвести проблему, если вместо этого использовал community technology preview edition of version 6.0 of the Microsoft JDBC driver (версия 6.0.6629.101).

+0

Luke ---> Ты отличный! Специально для того, чтобы идти дальше и дальше и тестировать это на MySql и Oracle. Я думал, что это проблема водителя, но подумал, что обзор кода будет уместным, прежде чем перейти к выводам. Я обязательно попробую просмотреть версию 6.0 и отчитаться! – TheStressMan

+0

@ user3225536: спасибо! У меня уже установлены базы данных MySQL и Oracle, поэтому для их проверки не потребовалось слишком много усилий. Код в вашем вопросе не сильно влияет на параметр ParameterMetaData, поэтому вы можете избежать ошибки, не получая метаданные параметров. Однако я подозреваю, что приведенный выше код был взят из реального кода, который требует использования параметра ParameterMetaData. Это верно? –

+0

Luke ---> ПараметрMetaData предназначен только для отладки. Это изначально представлялось при попытке «установить» параметры. Он жаловался, что их было недостаточно. Я бросил туда, чтобы увидеть, сколько там было. Остальная часть рассказа приведена выше.Опять же, я так ценю, что вы смотрите на это. Вторая пара глаз и обзор кода - это всегда хорошо. Спасибо! – TheStressMan

Смежные вопросы