VB.Net 和 SQL 命令未处理的异常

VB.Net and SQL Command Unhandled Exception

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

进口System.Data.SqlClient

Public Class Form1

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' 附近的语法不正确。如果此语句是一个常见的 table 表达式、一个 xmlnamespaces 子句或一个更改跟踪上下文子句,则前面的语句必须以分号结尾。'

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

您需要从 FIRSTROW

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

您的 class 将如下所示

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 在文件名周围有引号,但 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 table 名字
  • 为您的 FIRSTROW 使用 NumericUpDown
  • 考虑在其他字段中将“替换为”
  • 考虑将 seperator 文本框的长度限制为 MaxLength=1

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

谢谢大家,你们的所有回复对我帮助很大。我决定在项目上走另一条路,再次感谢!