Ошибка преобразования при преобразовании даты и времени из символьной строки
-
12-09-2019 - |
Вопрос
Строка, передаваемая моей пользовательской функции, выглядит следующим образом:
SELECT key FROM ubis WHERE MemberID = '144'
AND To >='11/7/2009 9:11:23 pm'
AND From <= '11/7/2009 9:11:23 pm'
Public Shared Function GetDataTable(ByVal CmdText As String) As DataTable
Dim myConn As New SqlConnection(ConfigurationManager.ConnectionStrings("Conn").ConnectionString)
Dim myCmd As New SqlCommand(CmdText, myConn)
myConn.Open()
Dim myReader As SqlDataReader = myCmd.ExecuteReader()
Dim myTable As New DataTable()
myTable.Load(myReader)
myConn.Close()
Return (myTable)
End Function
и вот ошибка, которую я получаю, Сбой преобразования при преобразовании даты и времени из символьной строки
Я понимаю, что поля datetime передаются в функцию в виде строки, но какие варианты у меня есть?
Решение
Вы пробовали запускать sql в managment studio и смотреть, что происходит?
Другие советы
Рассматривали ли вы возможность использования параметризованного запроса?Это решило бы вашу проблему и обеспечило бы дополнительную безопасность в случае, когда WHERE
условия взяты из пользовательского ввода.
Пример (VB.NET):
Dim myCmd As New SqlCommand(CmdText, myConn)
myCmd.Parameters.AddWithValue("MemberID", 144)
myCmd.Parameters.AddWithValue("Timestamp", DateTime.Now)
Используется с этим текстом запроса (SQL):
SELECT key FROM ubis WHERE MemberID = @MemberID
AND @Timestamp BETWEEN From AND To
Не по теме:в BETWEEN
ключевое слово в SQL - это просто аккуратный способ выразить >= AND <=
условия.
Это пахнет уязвимостью sql-инъекции.Эта дата случайно не исходила от пользователя (даже косвенно), не так ли?Даже если это безопасно, общие функции, такие как 'GetDataTable()', которые не учитывают правильные параметры запроса, почти всегда являются ошибкой.
Ты хочешь чего-то большего, подобного этому:
Public Shared Function GetMemberKeys(ByVal MemberID As Integer, ByVal KeyDate As DateTime) As DataTable
Static sql As String= _
"SELECT key" _
+ " FROM ubis" _
+ " WHERE MemberID= @MemberID AND @KeyDate BETWEEN [FROM] AND [TO]"
Dim dt As New DataTable()
Using cn As New SqlConnection(ConfigurationManager.ConnectionStrings("Conn").ConnectionString), _
cmd As New SqlCommand(sql, cn)
cmd.Parameters.Add("@MemberID", SqlDbType.Int).Value = MemberID
cmd.Parameters.Add("@KeyDate", SqlDbType.DateTime).Value = KeyDate
cn.Open()
Using rdr As SqlDataReader = cmd.ExecuteReader()
dt.Load(rdr)
End Using
End Using
Return dt
End Function
07.11.2009 неоднозначно - это 11 июля или 7 ноября?
SQL не имеет способа определить - и это зависит от значений по умолчанию, с которыми он был настроен.Было бы лучше передать дату в однозначном формате:
SELECT key FROM ubis WHERE MemberID = '144'
AND To >='11 July 2009 9:11:23 pm'
AND From <= '11 July 2009 9:11:23 pm'
В качестве альтернативы, используйте правильное преобразование с правильным код формата, или a пользовательский один, как было предложено Zyphrax:
SELECT key FROM ubis WHERE MemberID = '144'
AND To >= CONVERT(datetime, '11/7/2009 9:11:23 pm', 105)
AND From <= CONVERT(datetime, '11/7/2009 9:11:23 pm', 105)
Вы можете использовать команду CONVERT для преобразования символа в datetime.
SELECT key FROM ubis WHERE MemberID = '144'
AND To >= CONVERT(datetime, '11/7/2009 9:11:23 pm', 105)
AND From <= CONVERT(datetime, '11/7/2009 9:11:23 pm', 105)
Я не уверен насчет 105, возможно, вам придется поискать в Google код правильного формата.
Кроме того, если ваш SQL-код столкнется с исключением, ваше соединение не будет закрыто.Возможно, вы захотите добавить немного кода Using, чтобы исправить это.
Public Shared Function GetDataTable(ByVal CmdText As String) As DataTable
Using myConn As New SqlConnection(ConfigurationManager.ConnectionStrings("Conn").ConnectionString)
Using myCmd As New SqlCommand(CmdTxt, myConn)
conn.Open()
Using myReader As SqlDataReader = myCmd.ExecuteReader()
Dim myTable As New DataTable()
myTable.Load(myReader)
myConn.Close()
Return (myTable)
End Using
End Using
End Function