2012-03-01 2 views
3

Я работаю над приложением Java-сервера, которое использует Spring 3 и C3P0 для доступа к базе данных Microsoft SQL Server 2008 R2, используя версию 3.0 драйвера Microsoft JDBC 4.Почему мой параметр datetime для отложенной хранимой процедуры отклоняется?

У меня есть sproc, который имеет вход, определенный следующим образом:

@modifiedAfter datetime = NULL 

Я использую Spring построить вызов этой sproc.

Я построения MapSqlParameterSource содержать мои параметры:

MapSqlParameterSource in = new MapSqlParameterSource() 
in.addValue("modifiedAfter", "2011-01-01T00:00:00", Types.TIMESTAMP) 

Но когда я выполнить вызов:

this.sprocCall.execute(in); 

Я получаю это:

com.microsoft. sqlserver.jdbc.SQLServerException: преобразование не удалось при преобразовании даты и/или времени из строки символов

... и я понятия не имею, почему.

Я попробовал несколько вариантов добавления параметра, например, передать его как Date или указать его как VARCHAR или не указывая тип - ни одна из них не работает.

Я начинаю подозревать, что проблема может быть связана с весной. Я написал небольшой скрипт Groovy, чтобы попытаться изолировать проблему, и это работает просто отлично:

dt = new DateTime("2012-02-01T00:00:00") // Joda DateTime 
println sql.rows("exec spMySproc @modifiedAfter=${Sql.TIMESTAMP(dt.toString())}") 

... но когда я пытаюсь эквивалентный подход с MapSqlParameterSource, я получаю вышеуказанную ошибку.

На данный момент я в тупике.

Вот вершина StackTrace:

org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call spGetPoliciesCatalogPaged(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}]; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string. 
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:97) 
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) 
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:952) 
    at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:985) 
    at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallInternal(AbstractJdbcCall.java:368) 
    at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:342) 
    at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:164) 

... которые следуют некоторые из моих классов, то это:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string. 
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:197) 
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:4762) 
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1682) 
    at com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:955) 
    at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:2859) 
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:91) 
    at org.springframework.jdbc.core.JdbcTemplate.processResultSet(JdbcTemplate.java:1124) 
    at org.springframework.jdbc.core.JdbcTemplate.extractReturnedResults(JdbcTemplate.java:1023) 
    at org.springframework.jdbc.core.JdbcTemplate$5.doInCallableStatement(JdbcTemplate.java:995) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:936) 
    ... 68 more 

Я пытался обновить до последней версии spring-jdbc, 3.1. 1, но это не помогло.

Буду признателен за любую помощь!

Спасибо, Avi

+2

Вы пробовали строку вместо Types.TIMESTAMP? Я думаю, формат Format.TIMESTAMP не может быть преобразован в sql-сервер. –

+1

TIMESTAMP в SQL Server не имеет абсолютно никакого отношения к дате или времени. –

+0

@ThitLwinOo, @Aaron: Я не использую формат timestamp SQL Server. Я использую формат JDBC TIMESTAMP. В соответствии с [этой страницей] (http://msdn.microsoft.com/en-us/library/ms378878.aspx) драйвер JDBC сопоставляет формат JDBC TIMESTAMP с типами SQL Server 'datetime' и' datetime2'. Кроме того, описанный выше скрипт Groovy, который использует JDBC TIMESTAMP, работает отлично. –

ответ

2

Сотрудник по-моему понял это. Оказывается, я прыгнул с пистолета, обвинив Spring и/или драйвер Microsoft SQL Server. Проблема была действительно ошибкой при преобразовании символьной строки в дату/время - но это не было проблемой непосредственно с моим параметром, это была проблема с запросом, который выполнялся динамическим SQL, созданным моим sproc, если Я прошел в этом параметре.

Проблемный код выглядит примерно так:

IF @modifiedAfter IS NOT NULL BEGIN 
    SET @SQL = @SQL + N'AND mytable.ThingLastUpdated > @modifiedAfter' 
END 

После того, как динамический SQL, содержащийся в @SQL был фактически исполнен, содержание @modifiedAfter - это вполне допустимо DATETIME, посланный в от моего Java кода без каких-либо проблем в все - были сопоставлены с содержанием mytable.ThingLastUpdated - который был столбцом VARCHAR, что означало, что SQL Server должен был преобразовать его содержимое в DATETIME, чтобы их можно было сравнить с @modifiedAfter - но не все значения в mytable.ThingLastUpdated могли быть успешно преобразованы, следовательно, преобразование ошибка будучи брошенным.

Исправление, которое я решил изменить, должно было изменить тип mytable.ThingLastUpdated на DATETIME и сделать любое необходимое преобразование во время ввода, которое, по моему мнению, будет более эффективным, чем это во время запроса.

урок: если проблема SQL не в мой Java код, это, вероятно, в мой SQL - не весной или драйвер JDBC. PEBKAC.

1

Если бы подобную проблему и искал @ MSDN и выглядит как SQL-Server 2005 была ошибка с точностью преобразования. Предположительно, версия, которую вы используете, натолкнула точность 100ns. Будет ли возможно проверить точность отметки времени. Вот ссылка на обсуждение: Sql Server Conversion error

+0

В моем проблемном примере код имеет строгое кодирование: 'in.addValue (" modifiedAfter "," 2011-01-01T00: 00: 00 ", Types.TIMESTAMP)', поэтому вы можете видеть, что нет данных на уровне точности, который стандартный SQL Server DateTime не сможет представлять. –

+0

in.addValue ("modifiedAfter", "2011-01-01T00: 00: 00", Types.String), как насчет этого? Поскольку значение «2011-01-01T00: 00: 00» не является проблемой для преобразования в SQL-сервер. –

+0

@ThitLwinOo 'Types.String' не существует. Вы можете просмотреть список всех типов JDBC [здесь] (http://docs.oracle.com/javase/7/docs/api/java/sql/Types.html). Я попробовал 'Types.VARCHAR', и я получил ту же ошибку. –

1

Как насчет передачи ввода как String/varchar, а затем преобразования его в datetime в sproc?

+2

Хотя я думаю, что, вероятно, было бы подходящим обходным решением, и я ценю помощь, обходные пути - это не то, что я ищу - я хочу понять, почему мой код, который должен работать, не работает. –

1

Эта ошибка является defenitely не проблемой SQL bacause, которая преобразует эту строку "2011-01-01T00: 00: 00" в datetime успешно.Тип параметра sql, который вы указали, имеет тип TIMESTAMP, и вы передаете строку. Я думаю, что здесь не удается преобразовать.

Попробуйте объявить тип параметра sql как строку или varchar вместо TimeStamp.

+0

Как я уже упоминал в своем вопросе, я уже пробовал это. Это не работает. –

+0

Вы пытались предоставить какой-либо другой формат даты? – Virus

+0

Вы имеете в виду как значение или как указанный тип? Чтобы быть ясным, я уверен, что проблема здесь с Spring - я очень хорошо знаю, что семантика того, что я пытаюсь сделать, должна поддерживаться JDBC и MSSQL. Во всяком случае, я пробовал различные комбинации значений и указанных типов - объекты Java 'Date',' Types.VARCHAR' и т. Д. В этот момент я считаю, что Spring исследует sproc, видя, что параметр объявлен как «DATETIME», и пытаться принудить ценность к чему-то совместимому - и по какой-то причине не удается.Думаю, мне придется копать исходный код Spring ... –

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