【问题标题】:System.Data.SqlClient.SqlException: 'Incorrect syntax nearSystem.Data.SqlClient.SqlException:'附近的语法不正确
【发布时间】:2021-03-31 17:33:01
【问题描述】:

我不明白为什么会出现此错误:

System.Data.SqlClient.SqlException: '12' 附近的语法不正确。'

我的代码:

Imports System.Data.SqlClient
Public Class produktm
    Dim Con As New SqlConnection("Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\MON\Documents\profitmon.mdf;Integrated Security=True;Connect Timeout=30")
    Public Sub populate()
        Con.Open()
        Dim sql = "select * from ProduktTable"
        Dim adapter As SqlDataAdapter
        adapter = New SqlDataAdapter(sql, Con)
        Dim builder As SqlCommandBuilder
        builder = New SqlCommandBuilder(adapter)
        Dim ds As DataSet
        ds = New DataSet
        adapter.Fill(ds)
        ProduktDataList.DataSource = ds.Tables(0)

        Con.Close()
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Con.Open()
            Dim query As String
            query = "Insert Into ProduktTable values(" & ProduktId.Text & ",'" & ProdEmri.Text & ",'" & ProdSasia.Text & ",'" & ProdQmimi.Text & ",'" & ProdPershkrimi.Text & ",'" & ProdKategori.SelectedItem.ToString() & "')"
            Dim cmd As SqlCommand
            cmd = New SqlCommand(query, Con)
            cmd.ExecuteNonQuery()
            MsgBox("Produkti u shtua me sukses")
            Con.Close()

    End Sub

    Private Sub produktm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        populate()
    End Sub
End Class

Visual Studio 说这行是问题

        cmd.ExecuteNonQuery()

【问题讨论】:

  • 请停止喊叫。全部大写的文本更难阅读和理解,并且 SHOUTING 不会更快地为您提供帮助。当你向我们寻求帮助时,对我们大喊大叫也是相当不礼貌的。谢谢。
  • 如果动态生成 sql 语句,调试与执行相关的任何错误的第一部分是查看生成的语句。停止懒惰和坏习惯。始终在插入语句中指定列列表。
  • 所有关于 sql 注入和有效的东西并不是使用参数的最佳理由。真正作为一名开发人员,只是让执行大量的 sql 语句更简单、更易于维护、更令人愉快,而不是围绕 sting 连接出现的所有问题
  • 看起来你的单引号匹配了。仔细检查哪些值应该有单引号。我同意@SMor,生成您的 sql 语句以查看您传递给 SQL 的内容。

标签: sql-server vb.net visual-studio


【解决方案1】:

你缺少一些撇号:

query = "Insert Into ProduktTable values(" & ProduktId.Text & ",'" & ProdEmri.Text & ",'" & ProdSasia.Text & ",'" & ProdQmimi.Text & ",'" & ProdPershkrimi.Text & ",'" & ProdKategori.SelectedItem.ToString() & "')" 

应该是

query = "Insert Into ProduktTable values('" & ProduktId.Text & "','" & ProdEmri.Text & ",'" & ProdSasia.Text & "','" & ProdQmimi.Text & "','" & ProdPershkrimi.Text & "','" & ProdKategori.SelectedItem.ToString() & "')"

为了帮助,添加这一行:

Debug.WriteLine(query)

然后将输出复制/粘贴到 SSMS 中并进行测试

有更好的方法可以做到这一点,虽然不会让你接受 sql 注入,但这应该可以解决当前的问题。

【讨论】:

  • 问题和您的答案都受到 SQL 注入漏洞的影响。必填Little Bobby Tables 参考。
  • 您应该包含关于那些更好的方法的具体信息,并指出为什么连接 SQL 是一个非常糟糕的主意。这是一个旨在教育和分享知识的网站。
  • 抱歉,我有 5 分钟的时间,我想我会帮助初学者,因为我们都需要从某个地方开始。
  • mm 没用,我编辑了我的问题,如果你有时间请看一下
  • 确保您使用的是标准的双引号 (") 和单引号 ('),而 不是 是您在 Outlook 电子邮件中收到的字符。另外,请打破在赋值上并查看结果字符串。您甚至可以复制该字符串并尝试在 SSMS 中直接执行它。在代码中构造这些字符串时可能会很棘手,尤其是在变量本身可以包含引号的情况下。另外,请确保只有字符串类型用单引号括起来;不应该是数字类型。在尝试在代码中构造这些东西之前,您需要掌握基本的 SQL 语法,恕我直言。
【解决方案2】:

Set a breakpoint 到“查询”行并检查“查询”字符串。

试试下面的代码:

query = "Insert Into ProduktTable values('" & ProduktId.Text & "','" & ProdEmri.Text & "','" & ProdSasia.Text & "','" & ProdQmimi.Text & "','" & ProdPershkrimi.Text & "','" & ProdKategori.SelectedItem.ToString() & "')"

【讨论】:

    【解决方案3】:

    子填充()

    不要在类级别声明连接。它们需要关闭并使用Using...End Using 块进行处理。以使用它们的方法保持联系。要节省键入,请在类级别创建一个包含连接字符串的字符串变量。在使用之前不要打开连接,在.Execute... 之前。 DataAdapter.FillDataAdapter.Update 如果发现连接已关闭,将打开和关闭连接。您不需要DataSetCommandBuilderDataAdapter。您的DataAdapter 超出End Sub 的范围。不要将数据库代码与用户界面代码混在一起。

    Private Sub produktm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim dt = populate()
        ProduktDataList.DataSource = dt
    End Sub
    
    Public Function populate() As DatTable
        Dim dt As New DataTable
        Using Con As New SqlConnection(ConStr),
                cmd As New SqlCommand("select * from ProduktTable", Con)
            Con.Open()
            dt.Load(cmd.ExecuteReader)
        End Using
        Return dt
    End Function
    

    Button1_Click 和 InsertNewProductID

    在调用InsertNewProduct 之前,您将对按钮单击中的用户输入进行任何验证。始终将数据库字段名称作为插入的一部分列出。

    始终使用参数。

    我不得不猜测我在 Insert 语句中使用的列名。我还不得不猜测Parameters.Add 字段的数据类型和大小。请检查您的数据库以获取正确的值。

    我担心ProduktId 字段是一个自动编号的身份字段。如果是这样,则不应将其包含在 Insert 的字段列表中。不应该为它创建参数,也不应该传递任何值。数据库提供值。

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim RecordsEntered = InsertNewProduct(CInt(ProduktId.Text), ProdEmri.Text, ProdSasia.Text, ProdQmimi.Text, ProdPershkrimi.Text, ProdKategori.SelectedItem.ToString())
        If RecordsEntered = 1 Then
            MsgBox("Produkti u shtua me sukses")
        End If
    End Sub
    
    Private Function InsertNewProduct(Id As Integer, Emri As String, Sasia As String, Qmimi As String, Persh As String, Kategori As String) As Integer
        Dim RetVal As Integer
        Dim sql = "Insert Into ProduktTable (
                    ProduktId,
                    ProdEmri,
                    ProdSasia,
                    ProdQmimi,
                    ProdPershkrimi,
                    ProdKategori)
                    Values
                    (@ID, @Emri,@Sasia, @Qmimi, @Persh, @Kategori);"
        Using Con As New SqlConnection(ConStr),
                cmd As New SqlCommand(sql, Con)
            With cmd.Parameters
                .Add("@ID", SqlDbType.Int).Value = Id
                .Add("@Emri", SqlDbType.NVarChar, 100).Value = Emri
                .Add("@Sasia", SqlDbType.NVarChar, 100).Value = Sasia
                .Add("@Qmimi", SqlDbType.NVarChar, 100).Value = Qmimi
                .Add("@Persh", SqlDbType.NVarChar, 100).Value = Persh
                .Add("@Kategori", SqlDbType.NVarChar, 100).Value = Kategori
            End With
            Con.Open()
            RetVal = cmd.ExecuteNonQuery()
        End Using
        Return RetVal
    End Function
    

    这可能看起来有很大的变化,但正确使用参数以及处理连接和命令对于您的应用程序的整体成功非常重要。

    请检查我对字段和表名的拼写。我几乎不能拼写我自己的语言。 :-)

    【讨论】:

      猜你喜欢
      • 2019-07-17
      • 2017-12-08
      • 2014-05-09
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多