2016-02-22 1 views
2

я пытаюсь получить поле Max, где дата = сегодня, используя этот код:Неверный синтаксис рядом с '#'. VB.net с базой данных SQL

Dim todaydate = Format(Today.Date, "dd/MM/yyyy") 
    Dim sql1 As String = "Select max(snum) From tblbill where idate = #" & todaydate & "# " 
    Dim conn1 As SqlConnection = New SqlConnection(constr) 
    Dim cmd1 As SqlCommand = New SqlCommand(sql1, conn1) 
    conn1.Open() 
    Dim dr1 As SqlDataReader = cmd1.ExecuteReader 
    dr1.Read() 
    If IsDBNull(dr1(0)) Then 
     TextBox6.Text = 1 
    Else 
     TextBox6.Text = dr1(0) + 1 
    End If 
    dr1.Close() 
    cmd1.Dispose() 
    conn1.Close() 

но при запуске приложения я получил эту ошибку: Неправильный синтаксис около «#» , Может кто поможет!

+1

'#' дата разделителем для * доступа * SQL, используйте одинарные кавычки для T-SQL (и, возможно, агностический формат даты локали, такой как yyyymmdd). –

+2

@AlexK. - это плохой совет, потому что он все еще оставляет это открытым для SQL-инъекций. Правильный совет - использовать параметризованный запрос, который вообще не требует формата даты, специфичного для локали. –

+0

Опишите атаку, которая вызывает 'Format (Today.Date," dd/MM/yyyy ")', чтобы вернуть инъекционную строку? –

ответ

-3

Вы должны использовать апостроф вместо хэша здесь, было бы лучше, если бы вы могли использовать string.format, а также (вместо того, чтобы вручную конкатенации)

Dim sql1 As String = String.Format("select max(snum) from tblbill where idate='{0}'",todaydate) 
+0

Это, скорее всего, не удастся в ряде разных локалей. Также он открыт для SQL-инъекции, так что это плохая практика. –

9

В первую очередь USE PARAMETERISED QUERIES, конкатенации строки уязвимы для искаженного SQL, вредоносного SQL-инъекции и ошибок преобразования, кроме того, он останавливает повторное использование плана запроса, потому что новый план создается для каждого переданного значения. Это уже решает вашу проблему, потому что вам не нужно беспокоиться о том, какие квалификаторы использовать для какого типа данных (как указано в комментарии, вам нужно использовать ' вместо #, который предназначен для MS Access), это также означает, что вы не нужно беспокоиться о том, является ли формат DD/MM/YYYY или MM/DD/YYYY, вы говорите, что SqlCommand ожидает дату, поэтому региональные настройки ни на что не повлияют.

Во-вторых, это хорошая идея, чтобы использовать Using блоки, чтобы ваши IDisposable объекты очистить себя:

Dim sql1 As String = "Select max(snum) From tblbill where idate = @Date " 
Using conn1 As New SqlConnection(constr) 
Using cmd1 As New SqlCommand(sql1, conn1) 

    cmd1.Parameters.Add("@Date", SqlDbType.DateTime).Value = Today.Date 
    conn1.Open() 

    Using dr1 As SqlDataReader = cmd1.ExecuteReader 
     If IsDBNull(dr1(0)) Then 
      TextBox6.Text = 1 
     Else 
      TextBox6.Text = dr1(0) + 1 
     End If 
    End Using 

End Using 
+1

Наконец-то разумный ответ! –

+0

Да, это модельный ответ, простой и понятный. 6 голосов за час, поэтому консенсус молча доказывается, безусловно, стоит закладок для будущей справки ..... – Monty

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