VB. Net и SQL Исключение необработанной команды - PullRequest
0 голосов
/ 08 апреля 2020

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

Импортирует System.Data.SqlClient

Publi c Форма класса 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: '. Неверный синтаксис рядом с ключевым словом «с». Если этот оператор является распространенным табличным выражением, предложением xmlnamespaces или предложением контекста отслеживания изменений, предыдущий оператор должен заканчиваться точкой с запятой. '

Может кто-нибудь помочь мне выяснить, почему происходит ошибка?

Ответы [ 3 ]

1 голос
/ 08 апреля 2020

Ваш SQL имеет кавычки вокруг имени файла, но версия VB этого не делает (если только текстовое поле не содержит кавычек, но я думаю, что это маловероятно, учитывая сообщение об ошибке):

enter image description here

Ваш 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 имени таблицы
  • Используйте NumericUpDown для вашей FIRSTROW
  • Подумайте о замене 'на' 'в других полях
  • Рассмотрите возможность ограничения длины текстового поля seperator на MaxLength=1

Если вы не знаете, что такое SQL Взлом инъекций, прочитайте http://bobby-tables.com

0 голосов
/ 09 апреля 2020

Спасибо, ребята, все ваши ответы очень помогли мне. Я решаю go другой маршрут с проектом, еще раз спасибо!

0 голосов
/ 08 апреля 2020

Вам необходимо удалить двойную кавычку из вашего 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
...