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

时间:2019-09-21 17:44:37

标签: sql-server vb.net vb.net-2010

我收到此SQL Server错误,但我不知道问题出在哪里:

  

描述:在执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。

     

接收细节:System.Data.SqlClient.SqlException:'''附近的语法不正确。'

     

源错误:行:46

     

错误行:cmdsql.ExecuteNonQuery()

代码:

Dim connexcel As OleDbConnection
Dim daexcel As OleDbDataAdapter
Dim dsexcel As DataSet
Dim cmdexcel As OleDbCommand
Dim drexcel As OleDbDataReader

Dim connsql As SqlConnection
Dim dasql As SqlDataAdapter
Dim dssql As DataSet
Dim cmdsql As SqlCommand
Dim drsql As SqlDataReader

Private Sub import_excel_to_sql_server_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.CenterToScreen()
End Sub

Private Sub BtnImpExcelFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnImpExcelFile.Click
    On Error Resume Next
    OpenFileDialog1.Filter = "(* .xls) | * .xls | (*. Xlsx) | *. xlsx | All files (*. *) | *. * "
           OpenFileDialog1.ShowDialog()
    FileAdd.Text = OpenFileDialog1.FileName
    connexcel = New OleDbConnection("provider = Microsoft.ace.OLEDB.12.0; data source =" & FileAdd.Text & "; Extended Properties = Excel 8.0;")
    connexcel.Open()

    Dim dtSheets As DataTable = connexcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
    Dim listSheet As New List(Of String)
    Dim drSheet As DataRow

    For Each drSheet In dtSheets.Rows
        listSheet.Add(drSheet("TABLE_NAME").ToString())
    Next

    For Each sheet As String In listSheet
        ExcelSheetList.Items.Add(sheet)
    Next
End Sub

Private Sub ExcelSheetList_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExcelSheetList.SelectedIndexChanged
    daexcel = New OleDbDataAdapter("select * from [" & ExcelSheetList.Text & "]", connexcel)
    dsexcel = New DataSet
    daexcel.Fill(dsexcel)
    DGVImpData.DataSource = dsexcel.Tables(0)
    DGVImpData.ReadOnly = True
End Sub

Sub connections()
    connsql = New SqlConnection("data source =. \ MSSMLBIZ; initial catalog = MyInvoice; integrated security = true")
    connsql.Open()
End Sub

Private Sub BtnSaveImpData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSaveImpData.Click
    For line As Integer = 0 To DGVImpData.RowCount - 2
        Call connections()
        Dim save As String = "insert into InvoiceData values ​​('" & DGVImpData.Rows(line).Cells(0).Value & "', '" & DGVImpData.Rows(line).Cells(1).Value & "')"
    cmdsql = New SqlCommand(save, connsql)
        cmdsql.ExecuteNonQuery()
    Next
    MsgBox("data saved successfully")
    DGVImpData.Columns.Clear()
End Sub

2 个答案:

答案 0 :(得分:0)

将数据库对象保留在本地,这样就可以确保它们已关闭并已处置。用`Using ... End Using'封闭这些对象,即使出现错误也可以实现。您不需要DataAdapter,DataSet或DataReaders的变量。我建议对Excel连接字符串仅使用一个表单级变量,因为它在2种方法中使用。

Linq的一小部分将从DataTable获取检索到的工作表名称,并填充一个数组。然后可以使用.AddRange将数组传递到列表框。

我不会使用SelectedIndexChanged事件,因为用户很容易单击错误的表或改变主意。我使用了Button.Click事件来填充网格。

SQL连接字符串对我来说很奇怪。我建议您单独测试。如果不起作用,这是一个很好的资源。 https://www.connectionstrings.com/

我将在Insert语句中具体说明列名。将FirstColumnNameSecondColumnName替换为实际的列名。只要语句中的名称与Parameters.Add方法中的名称匹配,参数名称就可以是您希望的任何名称。我猜在数据类型和大小。检查数据库中的正确值。

我们仅在循环外部添加一次参数,然后仅在循环内部更改值。

Private ExcelConString As String

Private Sub BtnImpExcelFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnImpExcelFile.Click
    Dim strFileName As String
    Dim dtSheets As DataTable
    OpenFileDialog1.Filter = "(* .xls) | * .xls | (*. Xlsx) | *. xlsx | All files (*. *) | *. * "
    OpenFileDialog1.ShowDialog()
    strFileName = OpenFileDialog1.FileName
    ExcelConString = "provider = Microsoft.ace.OLEDB.12.0; data source =" & strFileName & "; Extended Properties = Excel 8.0;"
    Using connexcel = New OleDbConnection(ExcelConString)
        connexcel.Open()
        dtSheets = connexcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
    End Using
    Dim exSheets() As Object = (From dRow In dtSheets.AsEnumerable() Select dRow("TABLE_Name")).ToArray
    ExcelSheetList.Items.AddRange(exSheets)
End Sub

Private Sub DisplayData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DisplayData.Click
    Dim dt As New DataTable
    Using cn As New OleDbConnection(ExcelConString)
        'In older versions of Visual Studio you may have to use String.Format instead of the interpolated string.
        Using cmd As New OleDbCommand($"select * from [{ExcelSheetList.Text}];", cn)
            cn.Open()
            dt.Load(cmd.ExecuteReader)
        End Using
    End Using
    DGVImpData.DataSource = dt
    DGVImpData.ReadOnly = True
End Sub

Private Sub BtnSaveImpData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSaveImpData.Click
    Using cn As New SqlConnection("data source =. \ MSSMLBIZ; initial catalog = MyInvoice; integrated security = true")
        Using cmd As New SqlCommand("Insert Into InvoiceData (FirstColumnName, SecondColumnName) Values ​​(@FirstColumn, @SecondColumn);", cn)
            cmd.Parameters.Add("@FirstColumn", SqlDbType.VarChar, 100)
            cmd.Parameters.Add("@SecondColumn", SqlDbType.VarChar, 100)
            cn.Open()
            For line As Integer = 0 To DGVImpData.RowCount - 2
                cmd.Parameters("@FirstColumn").Value = DGVImpData.Rows(line).Cells(0).Value
                cmd.Parameters("@SecondColumn").Value = DGVImpData.Rows(line).Cells(1).Value
                cmd.ExecuteNonQuery()
            Next
        End Using
    End Using
    MsgBox("data saved successfully")
    DGVImpData.Columns.Clear()
End Sub

关于错误处理... On Error Resume Next通常在新代码中不使用。我们有Try...Catch...Finally个区块。代码运行后,在需要的地方添加这些块。

编辑

要使用String.Format ...

Using cmd As New OleDbCommand(String.Format("select * from [{0}];", ExcelSheetList.Text))

第一个参数是您希望在其中放置变量的字符串。它包含用大括号括起来的索引占位符。以下参数是您要用于占位符替换的变量。

答案 1 :(得分:0)

感谢您帮助我解决代码中的错误。这是没有System.Data.SqlClient.SqlException的最终代码:'''附近的语法不正确'。错误。

现在,我尝试在最后一节(下面提到)中改进代码,以定义用于导出数据的参数。因为我有大量数据要导出到SQL Server,所以出现超时错误。任何人都可以改进代码以快速将数据导出到SQL Server吗?

connsql.Open()“ System.InvalidOperationException:'超时已到期。从池中获取连接之前已经过了超时时间。这可能是因为所有池中的连接都在使用中,并且已达到最大池大小。

Dim connexcel As OleDbConnection
Dim daexcel As OleDbDataAdapter
Dim dsexcel As DataSet
Dim cmdexcel As OleDbCommand
Dim drexcel As OleDbDataReader


Dim connsql As SqlConnection
Dim dasql As SqlDataAdapter
Dim dssql As DataSet
Dim cmdsql As SqlCommand
Dim drsql As SqlDataReader

Private Sub Import_excel_to_sql_server_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Me.CenterToScreen()
End Sub

Private Sub PKGAbtnImpExcelFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PKGAbtnImpExcelFile.Click
    On Error Resume Next
    'OpenFileDialog1.Filter = "(*.xls)|*.xls|(*.xlsx)|*.xlsx|All files (*.*)|*.*"
    PKGAofdImpOpenExcel.ShowDialog()
    PKGAtxtImpFileAdd.Text = PKGAofdImpOpenExcel.FileName
    connexcel = New OleDbConnection("provider=Microsoft.ace.OLEDB.12.0;data source=" & PKGAtxtImpFileAdd.Text & ";Extended Properties=Excel 8.0;")
    connexcel.Open()


    Dim dtSheets As DataTable = connexcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, Nothing)
    Dim listSheet As New List(Of String)
    Dim drSheet As DataRow

    For Each drSheet In dtSheets.Rows
        listSheet.Add(drSheet("TABLE_NAME").ToString())
    Next

    For Each sheet As String In listSheet
        PKGAtxtImpExlSheetL.Items.Add(sheet)
    Next
End Sub

Private Sub PKGAtxtImpExlSheetL_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PKGAtxtImpExlSheetL.SelectedIndexChanged
    daexcel = New OleDbDataAdapter("select * from [" & PKGAtxtImpExlSheetL.Text & "]", connexcel)
    dsexcel = New DataSet
    daexcel.Fill(dsexcel)
    PKGAdgvImpData.DataSource = dsexcel.Tables(0)
    PKGAdgvImpData.ReadOnly = True
End Sub

最后一部分

Sub Connectonsql()
    connsql = New SqlConnection("Data Source=DESKTOP-MIQGJTK\MSSMLBIZ;Initial Catalog=PkGlobalAccounting;Integrated Security=True")
    connsql.Open() 
End Sub

Private Sub PKGAbtnImpSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PKGAbtnImpSave.Click
    For Line As Integer = 0 To PKGAdgvImpData.RowCount - 2
        Call Connectonsql()
        Dim save As String = "insert into Test values('" & PKGAdgvImpData.Rows(Line).Cells(0).Value & "','" & PKGAdgvImpData.Rows(Line).Cells(1).Value & "')"
        cmdsql = New SqlCommand(save, connsql)
        cmdsql.ExecuteNonQuery()
    Next
    MsgBox("Data Saved Successfully")
    PKGAdgvImpData.Columns.Clear()

End Sub

感谢您的帮助。