Как я могу разрешить исключение ExecucuteNonQuery, выбрасывающее Неверный синтекс рядом с '?' - PullRequest
0 голосов
/ 06 августа 2020
Dim StrSql = "update student set id=?"

Updated (StrSql,15)

Public Function Updated (ByVal strSql As String, ByVal ParamArray Parameters As String ())
    For Each x In Parameters
        cmd.Parameters.AddWithValue("?",x)
    Next

    cmd.ExecuteNonQuery()
End Function

Ответы [ 2 ]

2 голосов
/ 06 августа 2020

Вы не оставили нам много на go; как указывает jmcilhinney, вам нужно добавить больше деталей к будущим вопросам. Например, в этом у вас есть код, который вообще не компилируется, не упоминает типы каких-либо переменных, вы не указываете имя базы данных ...

... Я вполне уверен, что «Неправильный синтаксис рядом» - это SQL серверная вещь, и в этом случае вам нужно помнить, что он (повторно) использует именованные параметры, в отличие, например, от Access, который использует позиционные:

SQL Server:
strSql = "SELECT * FROM person WHERE firstname = @name OR lastname = @name"
...Parameters.AddWithValue("@name", "Lee")

Access:
strSql = "SELECT * FROM person WHERE firstname = ? OR lastname = ?"
...Parameters.AddWithValue("anythingdoesntmatterwillbeignored", "Lee")
...Parameters.AddWithValue("anythingdoesntmatterwillbeignoredalso", "Lee")

Это означает, что ваша функция должна стать немного умнее; возможно, передайте ParamArray KeyValuePair (Of String, Object)

Или, возможно, вам следует прекратить делать это прямо сейчас и переключиться на использование Dapper. Dapper принимает ваш запрос, применяет ваши параметры и возвращает вам объекты, если вы их запрашиваете:

Using connection as New SqlConnection(...)

  Dim p as List(Of Person) = Await connection.QueryAsync(Of Person)( _
    "SELECT * FROM person WHERE name = @name", _
    New With { .name = "John" } _
  )

  ' use your list of Person objects

End Using

Да, все это добавление параметров BS, выполнение программы чтения и преобразование результатов в Person .. Dapper делает все это. Запросы выполняются как connection.ExecuteAsync("UPDATE person SET name=@n, age=@a WHERE id=@id", New With{ .n="john", .a=27, .id=123 })

http://dapper-tutorial.net

0 голосов
/ 06 августа 2020

Пожалуйста, включите Option Strict. Это процесс, состоящий из двух частей. Сначала для текущего проекта - в обозревателе решений дважды щелкните «Мой проект». Слева выберите Compile. В раскрывающемся списке Option Strict выберите ON. Второй для будущих проектов - Go в меню «Инструменты» -> «Параметры» -> «Проекты и решения» -> «Настройки VB по умолчанию». В раскрывающемся списке Option Strict выберите ON. Это избавит вас от ошибок во время выполнения.

Updated(StrSql, 15)

Ваша обновленная функция вызывает массив String. 15 не является строковым массивом.

Функциям требуется тип данных для возврата.

cmd.Parameters.AddWithValue("?", X)

cmd не объявляется.

Невозможно получите ошибку, указанную вами в приведенном выше коде. Он даже не будет компилироваться, не говоря уже о запуске и выдаче ошибки.

Не очень полезно писать функцию, которая пытается быть c общей, но на самом деле очень ограничена.

Давайте начнем с вашего заявления об обновлении.

Dim StrSql = "update student set id=?"

Предоставленное вами утверждение обновит каждый идентификатор в таблице студентов до 15. Это то, что вы намеревались сделать? Поля ID меняются редко. Они предназначены для однозначной идентификации записи. Часто это поля с автонумерацией. Команда обновления будет использовать поле идентификатора, чтобы определить, какую запись нужно обновить.

Не используйте .AddWithValue. См. http://www.dbdelta.com/addwithvalue-is-evil/ и https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/ и еще один: https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications Вот еще https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html

Поскольку вы не сказали нам, какую базу данных вы используете, я предположил, что это Access из-за знака вопроса. Если это другая база данных, измените типы соединения, команды и dbType.

Using ... End Using block гарантирует, что соединение и команда закрываются и удаляются, даже если есть ошибка.

Private ConStr As String = "Your Connection String"

Public Function Updated(StudentNickname As String, StudentID As Integer) As Integer
    Dim RetVal As Integer
    Using cn As New OleDbConnection(ConStr),
            cmd As New OleDbCommand("Update student set NickName = @NickName Where StudentID = @ID", cn)
        cmd.Parameters.Add("@NickName", OleDbType.VarChar, 100).Value = StudentNickname
        cmd.Parameters.Add("@ID", OleDbType.Integer).Value = StudentID
        cn.Open()
        RetVal = cmd.ExecuteNonQuery
    End Using
    Return RetVal
End Function

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim RowsUpdated = Updated("Jim", 15)
    Dim message As String
    If RowsUpdated = 1 Then
        message = "Success"
    Else
        message = "Failure"
    End If
    MessageBox.Show(message)
End Sub

Этот код хранит код вашей базы данных отдельно от кода пользовательского интерфейса.

...