Member 13204422 Ответов: 3

Синтаксическая ошибка (отсутствует оператор) в VB


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


Imports System.Data.OleDb

Public Class Form1

    Dim provider As String
    Dim dataFile As String
    Dim connString As String
    Public myConnection As OleDbConnection = New OleDbConnection
    Public dr As OleDbDataReader

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        provider = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
        dataFile = "C:\Users\CADPC\Documents\Parts# Database.mdb"
        connString = provider & dataFile
        myConnection.ConnectionString = connString
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        myConnection.Open()
        oldpartText.Clear()
        newpartText.Clear()
        descriptionText.Clear()
        materialText.Clear()
        Dim str As String
        str = "SELECT * FROM Cnc_Parts_List WHERE  Old Part# = '" & inputText.Text & "'"
        Dim cmd As OleDbCommand
        cmd = New OleDbCommand(str, myConnection)
        dr = cmd.ExecuteReader()
        While dr.Read()
            oldpartText.Text = dr("Old Part#").ToString
            newpartText.Text = dr("New Part#").ToString
            descriptionText.Text = dr("Description").ToString
            materialText.Text = dr("Material").ToString
        End While
        myConnection.Close()
    End Sub
End Class


Сообщение об ошибке:
Exception thrown: 'System.Data.OleDb.OleDbException' in System.Data.dll
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><traceidentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled<description>Unhandled exception<appdomain>WindowsApp1.exe<exception><exceptiontype>System.Data.OleDb.OleDbException, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089<message>Syntax error (missing operator) in query expression 'Old Part# = '001-200''.<stacktrace>   at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
   at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object&amp; executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object&amp; executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object&amp; executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
   at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.OleDb.OleDbCommand.ExecuteReader()
   at WindowsApp1.Form1.Button1_Click(Object sender, EventArgs e) in C:\Users\CADPC\AppData\Local\Temporary Projects\WindowsApp1\Form1.vb:line 28
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message&amp; m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message&amp; m)
   at System.Windows.Forms.ButtonBase.WndProc(Message&amp; m)
   at System.Windows.Forms.Button.WndProc(Message&amp; m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp; msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
   at WindowsApp1.My.MyApplication.Main(String[] Args) in :line 81<exceptionstring>System.Data.OleDb.OleDbException (0x80040E14): Syntax error (missing operator) in query expression 'Old Part# = '001-200''.
   at System.Data.OleDb.OleDbCommand.ExecuteCommandTextErrorHandling(OleDbHResult hr)
   at System.Data.OleDb.OleDbCommand.ExecuteCommandTextForSingleResult(tagDBPARAMS dbParams, Object&amp; executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object&amp; executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object&amp; executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
   at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.OleDb.OleDbCommand.ExecuteReader()
   at WindowsApp1.Form1.Button1_Click(Object sender, EventArgs e) in C:\Users\CADPC\AppData\Local\Temporary Projects\WindowsApp1\Form1.vb:line 28
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message&amp; m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message&amp; m)
   at System.Windows.Forms.ButtonBase.WndProc(Message&amp; m)
   at System.Windows.Forms.Button.WndProc(Message&amp; m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG&amp; msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
   at WindowsApp1.My.MyApplication.Main(String[] Args) in :line 81


Что я уже пробовал:

я гуглил эту проблему в течение нескольких часов, любая помощь была бы признательна

Member 13204422

получив эту ошибку, забыл поставить в первом посте

Системы.Данных.Oledb. OleDbException: 'синтаксическая ошибка (отсутствующий оператор) в выражении запроса 'старая часть# = '001-200".'

[no name]

Вам нужно заключить ваши нечетные именованные имена таблиц в скобки.

3 Ответов

Рейтинг:
23

Dave Kreskowiak

Все достаточно просто. Вы не можете иметь столбец или таблицу с именем Old Part#. Пробелы на самом деле не допускаются без заключения в квадратные скобки "[]".

Ваш запрос должен быть

... WHERE [Old Part#] = 'value'


Ваш запрос также уязвим для атак SQL-инъекций. Не используйте конкатенацию строк для построения SQL-запросов. Google для "атаки SQL-инъекций", чтобы узнать, почему то, что вы делаете, так плохо, а затем найдите "VB.NET параметризованные запросы", чтобы узнать, что с этим делать.


Member 13204422

Спасибо за помощь, я обязательно посмотрю это, я действительно внес изменения, которые вы сказали, и я получаю новую ошибку

Системы.Данных.Oledb. OleDbException: "нет значения для одного или нескольких обязательных параметров".

это в строке 28( dr = cmd.Метода executereader() )

ZurdoDev

Разве сообщение об ошибке не ясно?

Member 13204422

но какой параметр, я все еще очень новичок в этом, скачал visual studio 3 дня назад и учил себя по книге, но это просто поставило меня в тупик по какой-то причине

ZurdoDev

Разве у вас нет только одного параметра? Во-первых, посмотрите, что делает ваш код. Вы позвонили в ЦМД.ExecuteReader, что означает, что объект команды теперь будет выполнен. Это строка кода, вызывающая ошибку, поэтому вы знаете, что она должна что-то делать с оператором sql.

Во-вторых, нажмите out на поле или используйте F9 (в зависимости от ваших настроек) и установите точку останова в коде. Вы увидите красную полосу, пересекающую линию. Это означает, что код перестанет работать и будет находиться в состоянии паузы, когда он доберется до этой строки. Затем вы можете пройти через код по одной строке за раз и проверить значения, которые находятся в ваших переменных и элементах управления. Поэтому вы можете точно видеть, что происходит. Это самый важный навык, который понадобится любому разработчику, - умение отлаживать свой код.

Dave Kreskowiak

Я думаю, это довольно очевидно. Вы помещаете параметр в свой SQL-оператор, но никогда не указываете его значение в последующем коде C#.

Maciej Los

Хорошая мысль!
5!

Рейтинг:
2

Patrice T

Не ваш вопрос, но все же проблема у вас есть.

str = "SELECT * FROM Cnc_Parts_List WHERE  Old Part# = '" & inputText.Text & "'"

Никогда не создавайте SQL-запрос путем конкатенации с пользовательскими вводами, он называется "SQL-инъекция", он опасен для вашей базы данных и подвержен ошибкам.
Одна кавычка в имени - и ваша программа рухнет. Если пользовательский ввод типа "Брайан О'Коннер" может привести к сбою вашего приложения, то это уязвимость SQL-инъекции.
SQL-инъекция-Википедия[^]
SQL-инъекция[^]


Рейтинг:
14

Maciej Los

В дополнение к решению №1 Дэйва Кресковяка есть одна очень важная вещь, которую вы должны знать.

Ваш код таков SqlInjection[^] уязвимый!

Никогда не используйте такие запросы:

str = "SELECT * FROM Cnc_Parts_List WHERE  [Old Part#] = '" & inputText.Text & "'"

Вместо этого используйте параметризованные запросы:
str = "SELECT * FROM Cnc_Parts_List WHERE  [Old Part#] = @part;"

Тогда вам придется изменить свой OleDbCommand около добавление[^] @part параметр.
cmd.Parameters.AddWithValue("@part", inputText.Text)

Теперь вы можете выполнить этот запрос.

Примечание: MS Access database engine любит [;] в конце запроса!


Для получения более подробной информации о SQLInjection, пожалуйста, смотрите:
Как: защита от SQL-инъекций в ASP.NET[^]
Как: защититься от инъекционных атак в ASP.NET[^]
SQL-инъекция и как ее избежать – ASP.NET отладка[^]