2009-07-11 6 views
1

Строка, передаваемая в моей пользовательской функции выглядит следующим образом:Конверсия удалось при преобразовании DateTime из строки символов

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 из строки символов

Я понимаю, что поля datetime передаются как строка в функцию, но какие параметры у меня есть?

ответ

1

Вы пробовали запустить sql в студии управления и посмотреть, что происходит?

+0

Визуальная студия проходила в греческом Datetime (pm была отправлена ​​как «μμ») – OrElse

1

11/7/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' 

В качестве альтернативы, используйте правильное преобразование с правильным format code или custom one, как это было предложено 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) 
+0

11 июля ... сегодня – OrElse

+0

11 июля в греческом формате! dd/MM/yyyy – OrElse

+0

Если ваш SQL-сервер настроен для дат США, он будет интерпретировать дату как 7 октября. – Oded

0

Вы можете используйте команду CONVERT для преобразования символа в дату и время.

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 встречает исключение, ваше соединение не будет закрыто. Возможно, вы захотите добавить немного кода использования, чтобы исправить это.

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 
2

Считаете ли вы использование параметризованного запроса? Это решит вашу проблему и даст дополнительную безопасность в случае, когда условия 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 

Off-тема: BETWEEN ключевое слово в SQL только аккуратный способ выразить условия >= AND <=.

2

Это запах уязвимости в 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 
Смежные вопросы