Работа с датами в формате дд / мм / гггг - PullRequest
1 голос
/ 18 февраля 2009

У меня есть приложение VB6, которое работает со значениями даты и времени в SQL Server (которые, очевидно, хранят даты в виде мм / дд / гггг).

Мне нужно представить эти даты пользователю как дд / мм / гггг, прочитать их как дд / мм / гггг, а затем сохранить их обратно в базу данных как стандартные мм / дд / гггг.

Это текущие фрагменты кода, которые у меня есть, которые вытащить + вставить даты, однако я прочитал много противоречивых методов обработки преобразований, и мне было интересно, если кто-нибудь здесь знал четкое решение для этой ситуации.

"SELECT * FROM List WHERE DateIn LIKE '%" & txtDateIn.Text & "%'"

"UPDATE [Progress] SET [Date] = '" & txtDate.Text & "'"

txtDate.Text = "" & RecordSet.Fields("Date").Value

Есть мысли? Заранее спасибо.

** Обновление

На самом деле я только что заметил, что у меня есть даты, хранящиеся в полях datetime в форме 16/08/2009 00:00:00, которая является дд / мм / гггг. Так что, возможно, я неправильно понял проблему. Но при попытке обновить значение datetime у меня получалось «Преобразование типа данных char в тип данных datetime привело к значению datetime вне диапазона.».

Я предположил, что это произошло из-за того, что форматы даты не совпадали (что вызвало проблему с наличием значения месяца вне диапазона), однако у меня уже есть значения даты в формате день / месяц / год в поле даты и времени. И дата отправки в базу данных определенно дд / мм / гггг.

**** Обновление 2 **

Ладно, похоже, у меня возникла путаница. Я прошу прощения.

  • Я храню даты как дату и время в базе данных SQL
  • Тексты - это элементы управления TextBox в приложении VB6
  • Я выполняю операторы SQL SELECT, чтобы прочитать даты из базы данных и поместить значение в TextBox
  • Затем у меня есть командная кнопка 'commit', которая затем выполняет инструкцию SQL UPDATE, чтобы поместить значение TextBox в поле datetime в базе данных SQL
  • Это прекрасно работает до 1 конкретного случая.

В этом случае у меня есть значение datetime (которое SQL Server 2005 отображает как 16/08/2009 00:00:00), которое считывается из базы данных и заполняет TextBox значением 16/08/2009. Теперь, когда я пытаюсь выполнить инструкцию UPDATE без изменения текста TextBox, я получаю ошибку «Преобразование типа данных char в тип данных datetime привело к значению datetime вне диапазона».

Этого не происходит с другими записями, такими как запись с датой 04/08/2009, поэтому единственная проблема, которую я могу видеть, это, возможно, позиция дня и месяца в значении, потому что, если DB ожидает сначала месяц, то очевидно 16/08/2009 было бы вне диапазона. Однако значение в базе данных уже 16/08/2009 без проблем.

Ответы [ 3 ]

9 голосов
/ 18 февраля 2009

SQL Server «явно» не хранит даты в формате мм / дд / гггг. Насколько я знаю, он вообще не сохраняет их в текстовом формате.

Я не знаю, какова поддержка VB6 для параметризованных запросов, но это то, что вы хотите: в основном вы хотите передать аргумент в запрос как дату, а не как текст. По сути, вы должны проанализировать вводимые пользователем данные в дату (каким бы образом VB6 это не делал), а затем передать ее в параметризованном запросе.

РЕДАКТИРОВАТЬ: я пытался выяснить, как VB6 обрабатывает параметризованные запросы, и мне не повезло - надеюсь, любая хорошая книга по VB6 расскажет об этом. (Конечно, есть множество примеров для VB.NET ...) Есть сообщение Wrox , которое дает пример; этого может быть достаточно, чтобы вы пошли.

РЕДАКТИРОВАТЬ: Как видно из комментария к этому ответу и редактирования этого вопроса, существует некоторая путаница в отношении того, какими на самом деле являются ваши типы данных. Пожалуйста, не используйте символьные поля для хранения дат: ничего хорошего из этого не выйдет. Используйте правильное поле date / datetime / what, а затем убедитесь, что вы используете параметризованные запросы для доступа к базе данных, чтобы драйвер мог выполнять любые необходимые преобразования. Полагаться на текстовый формат - плохая идея.

5 голосов
/ 18 февраля 2009

Используйте ODBC Каноническую форму даты или отметки времени в своих запросах. Это позволяет избежать недоразумений из-за локализации при сохранении дат. Формат отметки времени: {ts 'гггг-мм-дд чч: мм: сс [.fff]'} Формат даты: {d 'гггг-мм-дд'} Вот функции, которые я использую для этого.

Теперь как для ввода и отображения в VB6. В идеале вы должны использовать элемент управления datetimepicker вместо текстового поля, поскольку оно возвращает дату, и при ее использовании не возникает недоразумений относительно того, какую дату вы выбираете. Но если вы можете предположить, что это всегда DD / MM / YYYY (это большое значение if), вы можете использовать Format (datevalue, "DD / MM / YYYY"), чтобы отобразить его. Чтобы прочитать это в переменную даты, вы не можете просто использовать CDate. Вам понадобится использовать синтаксический анализ и что-то вроде DateSerial, чтобы соединить это: DateSerial (Right (strDate, 4), Mid (strDate, 4, 2), Mid (strDate, 1, 2)).

' ------------------------------------------------------------------------------
' DateLiteral
'
' Description :
'    given a vb date, it returns a string with the odbc canonical date format.
'
' History
' 2008-02-04 - WSR : added to this project
'
Public Function DateLiteral(ByRef dtSource As Date) As String

    DateLiteral = _
        "{d '" & LeftPadDigits(Year(dtSource), 4) & "-" & _
                 LeftPadDigits(Month(dtSource), 2) & "-" & _
                 LeftPadDigits(Day(dtSource), 2) & "'}"

End Function
' ------------------------------------------------------------------------------


' ------------------------------------------------------------------------------
' TimeStampLiteral
'
' Description :
'    given a vb date, it returns a string with the odbc canonical timestamp format.
'
' History
' 2008-02-04 - WSR : added to this project
'
Public Function TimeStampLiteral(ByRef dtSource As Date) As String

    TimeStampLiteral = _
        "{ts '" & LeftPadDigits(Year(dtSource), 4) & "-" & _
                 LeftPadDigits(Month(dtSource), 2) & "-" & _
                 LeftPadDigits(Day(dtSource), 2) & " " & _
                 LeftPadDigits(Hour(dtSource), 2) & ":" & _
                 LeftPadDigits(Minute(dtSource), 2) & ":" & _
                 LeftPadDigits(Second(dtSource), 2) & "'}"

End Function
' ------------------------------------------------------------------------------


' ------------------------------------------------------------------------------
' LeftPadDigits
'
' Description : pads the given string to the left with zeroes if it is under
'    the given length so that it is at least as long as the given length.
'
' History
' 2008-02-04 - WSR : added to this project
'
Public Function LeftPadDigits(ByVal strSource As String, ByVal lngLength As Long) As String

    If Len(strSource) < lngLength Then
        LeftPadDigits = String$(lngLength - Len(strSource), "0") & strSource
    Else
        LeftPadDigits = strSource
    End If

End Function
' ------------------------------------------------------------------------------ 

Также следует отметить, что да, первым выбором является использование ADO и параметризованных запросов. В моем случае я обращаюсь к базе данных через стороннюю библиотеку и не могу использовать параметризованные запросы. Таким образом дата обработки буквально. Вот пример параметризованных запросов ADO. Код может отличаться в зависимости от того, какой тип соединения ADO вы используете: OLEDB, ODBC или SQLNative. Иногда это не просто? для маркера параметра. Этот пример OLEDB.

Set cmdVerifyUser = New ADODB.Command
cmdVerifyUser.CommandType = adCmdText
cmdVerifyUser.CommandTimeout = 30
cmdVerifyUser.CommandText = "SELECT username FROM users WHERE userid = ?"
cmdVerifyUser.Parameters.Append cmdVerifyUser.CreateParameter("userid", adVarChar, adParamInput, Len(m_strUserName), m_strUserName)
cmdVerifyUser.ActiveConnection = m_conDatabase
Set rstResults = cmdVerifyUser.Execute()

If Not rstResults.EOF Then
0 голосов
/ 18 февраля 2009

Ну, после всего этого проблема была проста. У меня есть значение даты, заключенное в одинарные (') и двойные (") кавычки. Проблема возникла из-за того, что значения даты не требуют одинарных кавычек. Удаление их решило проблему.

В любом случае, спасибо за попытку помочь всем.

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