【问题标题】:VB.Net and SQL Command Unhandled ExceptionVB.Net 和 SQL 命令未处理异常
【发布时间】:2020-04-08 08:04:59
【问题描述】:

我正在构建一个用于批量加载到 SQL 中的简单程序。但是我无法弄清楚这个错误。原始代码在下面,然后是没有文本框引用的翻译代码。

导入 System.Data.SqlClient

公开课表1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click

    Dim SQLCONN As New SqlConnection
    Dim SQLCMD As New SqlCommand
    SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
    SQLCONN.Open()
    SQLCMD = New SqlCommand("BULK INSERT " + table.Text +
        " FROM " + path.Text +
        "  With (FIRSTROW = '" + firstrow.Text + "',
            FIELDTERMINATOR = '" + seperator.Text + "',
            ROWTERMINATOR= '\n');", SQLCONN)
    SQLCMD.ExecuteNonQuery()
    SQLCONN.Close()

End Sub

这是 SQL 部分将转换为的内容

SQLCMD = New SqlCommand("BULK INSERT test1
         FROM  'C:\Program Files\Servers\FFA\csgo\maplist.txt'
          With (FIRSTROW = '2',
            FIELDTERMINATOR = ' ',
            ROWTERMINATOR= '\n')";, SQLCONN)

这是我得到的错误:

System.Data.SqlClient.SqlException: 'C:' 附近的语法不正确。 关键字“with”附近的语法不正确。如果此语句是公用表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前面的语句必须以分号结束。'

谁能帮我弄清楚为什么会出错?

【问题讨论】:

  • 应该以FIRSTROW = 2 结尾,即没有引号。此外,VB.NET 中的字符串连接运算符是&,而不是+

标签: sql-server vb.net sqlcmd


【解决方案1】:

您的 SQL 在文件名周围有引号,但 VB 版本没有(除非文本框本身包含引号,但我认为鉴于错误消息不太可能):

如果您使用字符串插值并在构建字符串之外进行一些预处理,您的 SQL 将更具可读性:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click

    Dim SQLCONN As New SqlConnection
    Dim SQLCMD As New SqlCommand
    SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
    SQLCONN.Open()

    Dim p = path.Text.Replace("'","''")
    Dim f = seperator.Text.Replace("'","''")

    SQLCMD = New SqlCommand($"BULK INSERT QUOTENAME({table.Text})
                FROM '{p}'
                WITH (FIRSTROW = {firstrowNumericUpdown.Value}
                FIELDTERMINATOR = '{f}',
                ROWTERMINATOR= '\n')", SQLCONN)
    SQLCMD.ExecuteNonQuery()
    SQLCONN.Close()

End Sub

您还应该尽最大努力防止 SQL 注入;您将用户交给了几个文本框,他们在其中输入内容,如果他们决定在文本框中编写一些 SQL,这可能会非常危险

  • 考虑使用 QUOTENAME 作为表名
  • 为您的 FIRSTROW 使用 NumericUpDown
  • 考虑在其他字段中将 ' 替换为 ''
  • 考虑将seperator 文本框的长度限制为MaxLength=1

如果您不知道什么是 SQL 注入黑客,请阅读 http://bobby-tables.com

【讨论】:

    【解决方案2】:

    您需要从 FIRSTROW 值中删除双引号

    SQLCMD = New SqlCommand("BULK INSERT test1
             FROM  'C:\Program Files\Servers\FFA\csgo\maplist.txt'
              With (FIRSTROW = 2,
                FIELDTERMINATOR = ' ',
                ROWTERMINATOR= '\n')";, SQLCONN)
    

    你的课程如下所示

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles insert.Click
    
        Dim SQLCONN As New SqlConnection
        Dim SQLCMD As New SqlCommand
        SQLCONN = New SqlConnection("Server=" + server.Text + ";Database=" + database.Text + ";Integrated security=True")
        SQLCONN.Open()
        SQLCMD = New SqlCommand("BULK INSERT " + table.Text +
            " FROM " + path.Text +
            "  With (FIRSTROW = " + firstrow.Text + ",
                FIELDTERMINATOR = '" + seperator.Text + "',
                ROWTERMINATOR= '\n');", SQLCONN)
        SQLCMD.ExecuteNonQuery()
        SQLCONN.Close()
    
    End Sub
    

    【讨论】:

      【解决方案3】:

      谢谢大家,你们所有的回答都对我有很大帮助。我决定与项目走不同的路线,再次感谢!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多