выберите записи, истекающие в течение следующих 30 дней - заявление SQL - PullRequest
0 голосов
/ 05 февраля 2019

тип данных: timestamp имя столбца: dlExpiryDate

SELECT * 
  FROM QUALIFICATION  
 WHERE dlExpiryDate >= NOW() 
   AND dlExpiryDate < NOW() + INTERVAL 1 MONTH;

Попытка получить большое количество запросов, чтобы получить ответ, но он не работает.Кто-нибудь получил ответ, чтобы решить это.Есть пример, который я пробовал выше, но он не работает.Распечатывается трассировка стека:

Тяжелая: java.sql.SQLSyntaxErrorException: синтаксическая ошибка: обнаружена «1» в строке 1, столбце 93 в org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Неизвестный источник) в org.apache.derby.client.am.SqlException.getSQLException (Неизвестный источник) в org.apache.derby.client.am.Statement.executeQuery (Неизвестный источник) в org.apache.jsp.viewQualification_jsp._jspService(viewQualification_jsp.java:105) в org.apache.jasper.runtime.HttpJspBase.service (HttpJspBase.java:111) в javax.servlet.http.HttpServlet.service (HttpServlet.java:790) в org.Сервлетв javax.servlet.http.HttpServlet.service (HttpServlet.java:790) в org.apache.catalina.core.StandardWrapper.service (StandardWrapper.java:1682) в org.apache.catalina.core.StandardWrapperValve.invoke (StandardWrapperValve.java:318) по адресу org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:160) по адресу org.apache.catalina.core.StandardPipeline.doInvoke или по стандарту: 7).apache.catalina.core.StandardPipeline.invoke (StandardPipeline.java:673) в com.sun.enterprise.web.WebPipeline.invoke (WebPipeline.java:99) в org.apache.catalina.core.StandardHostValve.invoke (StandardH.java: 174) в org.apache.catalina.connector.CoyoteAdapter.doService (CoyoteAdapter.java:416) в org.apache.catalina.connector.CoyoteAdapter.service (CoyoteAdapter.java:283) в com.sun.enterprise.v3.services.impl.ContainerMapper $ HttpHandlerCallable.call (ContainerMapper.java:459) по адресу com.sun.enterprise.v3.services.impl.ContainerMapper.service (ContainerMapper.java:167) по адресу org.glassfish.grizzly.http.server.HttpHandler.runService (HttpHandler.java:206) в org.glassfish.grizzly.http.server.HttpHandler.doHandle (HttpHandler.java:180) в org.glassfish.grizzly.http.server.HttpServerFilter.org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart (DefaultFilterChain.java:200) по адресу org.glassfish.grizzly.filterchain.DefaultFilterChain.execute (DefaultFilterChain.jzz:132) на org.gefhafter (DefaultFilterChain.java:111) в org.glassfish.grizzly.ProcessorExecutor.execute (ProcessorExecutor.java:77) в org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent (TCPNIOTransport.java:536) в org.glass.g.strategies.AbstractIOStrategy.fireIOEvent (AbstractIOStrategy.java:112) в org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0 (WorkerThreadIOStrategy.java:117) в org.glassfish.grizzly.strategiesI56) в орг.glassfish.grizzly.strategies.WorkerThreadIOStrategyWorker.run (AbstractThreadPool.java:571) в java.lang.Thread.run (Thread.java:745), вызванный: org.apache.derby.client.am.SqlException: синтаксическая ошибка: обнаружена «1» в строке 1, колонка 93. вorg.apache.derby.client.am.Statement.completeSqlca (Неизвестный источник) в org.apache.derby.client.net.NetStatementReply.parsePrepareError (Неизвестный источник) в org.apache.derby.client.net.NetStatementReply.parrepPRSTНеизвестный источник) в org.apache.derby.client.net.NetStatementReply.readPrepareDescribeOutput (Неизвестный источник) в org.apache.derby.client.net.StatementReply.readPrepareDescribeOutput (Неизвестный источник) в org.apache.derby.client.net.NetStatement.readPrepareDescribeOutput_ (неизвестный источник) по адресу org.apache.derby.client.am.Statement.readPrepareDescribeOutput (неизвестный источник) по адресу org.apache.derby.client.am.Statement.flowExecute (неизвестный источник) по адресу org.apache.der.client.am.Statement.executeQueryX (Неизвестный источник) ... еще 36

Кто-нибудь получил ответ на этот вопрос, пожалуйста?Спасибо

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Часовой пояс

Имейте в виду, что тип TIMESTAMP в Derby подобен стандартному типу SQL TIMESTAMP WITHOUT TIME ZONE (по крайней мере, похоже, что документация плохонаписано).Это означает, что в этом типе отсутствует понятие часовой пояс или смещение от UTC .Таким образом, этот тип не представляет конкретный момент, точку на временной шкале.Вместо этого он представляет потенциальных моментов в диапазоне около 26-27 часов, диапазоне часовых поясов по всему земному шару.

Например, если вы хранили полдень 23 января 2019 годаМы не знаем, имели ли вы в виду полдень в Токио, Япония, или несколько часов раньше, когда полдень в Калькутте, Индия.Или, может быть, вы имели в виду часы спустя, полдень в Париже, Франция.Или еще несколько часов спустя, когда в Монреаль Квебек прибудет полдень.Такое значение в этом типе будет означать полдень 23-го в любом месте , для любого из многих моментов в диапазоне 26-27 часов.

Так что не имеет смысла делатьзапрос на этот тип при сравнении с текущим моментом.

Но…

Если вы обрабатываете часовой пояс в своем приложении и делаете вид, что все значения в базе данных относятся к определенному часовому поясу, используйте эту зону при захвате текущего момента.

ZonedDateTime

В классах java.time мы используем ZonedDateTime для представления момента во времени настенных часовиспользуется людьми определенного региона (часового пояса).

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;  // Capture the current moment as seen in the wall-clock time used by the people of a particular region (a time zone).

Сброс ценной информации о зоне / смещении с помощью LocalDateTime

Мы можем удалить информацию о часовом поясе, оставив толькодата и время суток в объекте LocalDateTime.

LocalDateTime ldt = zdt.toLocalDateTime()

Начало дня

Если вы ищете месяц, вы, вероятно, захотитеначать в начале дня.На мгновение мы позволим java.time определить первый момент дня, так как день не всегда начинается в 00:00 из-за таких аномалий, как летнее время (DST).Но в LocalDateTime отсутствует зона / смещение, мы не можем объяснить такие аномалии.Поэтому мы просто перейдем к 00:00.

LocalDateTime ldtStartOfDay = ldt.with( LocalTime.MIN ) ;

Математика даты и времени

Чтобы добавить ваш месяц, мы можем сделать математику даты и времени, используя методы plus… и minus….

LocalDateTime ldtMonthLater = ldtStartOfDay.plusMonths() ;

Заполнители SQL

Передайте эти значения для замены заполнителей в SQL в подготовленном выражении.

SELECT * 
FROM QUALIFICATION  
WHERE dlExpiryDate >= ?
AND dlExpiryDate < ?
;

JDBC 4.2

Начиная с JDBC 4.2 и выше, мы можем напрямую обмениваться объектами java.time с базой данных, используя setObject & getObject.Нет необходимости использовать ужасные классы, такие как java.sql.Timestamp.

myPreparedStatement.setObject( 1 , ldtStartOfDay) ;
myPreparedStatement.setObject( 2 , ldtMonthLater) ;

При получении.

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

Рассмотрим другие базы данных

Возможно, вы захотите рассмотреть возможность использования других баз данных.Oracle прекратила связывать Derby как Java DB , так как было установлено, что он не подходит для производственного использования.

Если вам нужна база данных с открытым исходным кодом, написанная на Java, я бы предложил H2 Database Engine , подходящий как для встроенного использования, так и для сервера.Если вам нужен сервер баз данных с открытым исходным кодом, созданный для работы в тяжелых условиях корпоративного качества, я предлагаю Postgres .


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , советует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .

Вы можете обмениваться java.time объектами напрямую с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где взять классы java.time?

  • Java SE 8 , Java SE 9 , Java SE 10, Java SE 11 и более поздние версии - часть стандартного Java API с связанной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и JavaSE 7
    • Большинство функций java.time перенесено в Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии реализации связки Android java.time классы.
    • Для более ранних версий Android (<26) проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP адаптируется ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .

ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и more .

0 голосов
/ 05 февраля 2019

Если вы хотите выполнить этот запрос без учета базы данных, разрешите 2 даты в коде Java и укажите их, используя PreparedStatement.

LocalDate today = LocalDate.now();
String sql = "SELECT *" +
              " FROM QUALIFICATION" +
             " WHERE dlExpiryDate >= ?" +
               " AND dlExpiryDate < ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
    stmt.setDate(1, java.sql.Date.valueOf(today));
    stmt.setDate(2, java.sql.Date.valueOf(today.plusMonths(1)));
    try (ResultSet rs = stmt.executeQuery()) {
        // code here
    }
}

В зависимости от драйвера JDBC (например, неMicrosoft), вы также можете использовать setObject.

stmt.setObject(1, today);
stmt.setObject(2, today.plusMonths(1));
...