Jennifer Paige Jones Ответов: 3

Исключение Sql: недопустимое имя столбца


Цитата:
System.Data.SqlClient.SqlException: 'недопустимое имя столбца 'кружки'.'


Я не уверен в ошибке, так как скопировал ее из фрагмента кода на другой форме, которая отлично работает.

Я извлекаю информацию из базы данных, используя текст с кнопки. Кнопка помечена как "кружки", а описание товара также помечено как "кружки". Имя столбца "наименование".

Все переменные являются общедоступными из формы 1.

Код:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If Form1.lst_Receipt.Items.Count = 0 Then
            Form1.noitemcost = 0
            Form1.noitemtax = 0
            Form1.noitemtotal = 0
            Form1.lst_Receipt.Items.Add("UTA Planetarium")
            Form1.lst_Receipt.Items.Add(FormatDateTime(Today, DateFormat.LongDate))
            Form1.lst_Receipt.Items.Add(FormatDateTime(Today, DateFormat.LongTime))
            Form1.lst_Receipt.Items.Add(" ")
            Form1.lst_Receipt.Items.Add("SubTotal: $" + Form1.noitemcost.ToString)
            Form1.lst_Receipt.Items.Add("Tax: $" + Form1.noitemtax.ToString("F2"))
            Form1.lst_Receipt.Items.Add("Total: $" + Form1.noitemtotal.ToString("F2"))
        End If

        If Form1.reset = 1 Then
            Form1.subtotal = 0
            Form1.tax = 0
            Form1.total = 0
            Form1.tickettax = 0
            Form1.reset = 0
        End If

        Form1.itemdesc = Button1.Text

        Form1.sqlConnection1.Open()

'I believe the next line is where it is hanging up at.
        Form1.cmd = New SqlClient.SqlCommand("SELECT * FROM Inventory WHERE [ItemDescription] =" + Form1.itemdesc, Form1.sqlConnection1)

        Form1.reader = Form1.cmd.ExecuteReader
        Form1.reader.Read()
        Form1.itemcost = Form1.reader(11)
        Form1.proddesc = Form1.reader(3)
        'Form1.itemdesc = Form1.reader(2)
        'itemdesc = reader(2).ToString


        Form1.sqlConnection1.Close()

        Form1.lst_Receipt.Items.RemoveAt(Form1.lst_Receipt.Items.Count - 1)
        Form1.lst_Receipt.Items.RemoveAt(Form1.lst_Receipt.Items.Count - 1)
        Form1.lst_Receipt.Items.RemoveAt(Form1.lst_Receipt.Items.Count - 1)
        Form1.lst_Receipt.Items.Add(Form1.proddesc + vbTab + Form1.quantity + vbTab + Form1.itemcost.ToString("F2"))
        Form1.lst_Receipt.Items.Add("SubTotal: $" + Form1.subtotal.ToString("F2"))
        Form1.lst_Receipt.Items.Add("Tax: $" + Form1.tax.ToString("F2"))
        Form1.lst_Receipt.Items.Add("Total: $" + Form1.total.ToString("F2"))
        Form1.TextBox1.Text = String.Empty
        Form1.TextBox2.Text = ""
        Form1.TextBox1.Focus()
        Close()
    End Sub


Это находится в коробке с надписью "немедленное окно":

ClientConnectionId:dfec050c-bd3f-4cef-9e0e-ad871a9487e2
Error Number:207,State:1,Class:16</ExceptionString><DataItems><Data><Key>HelpLink.ProdName</Key><Value>Microsoft SQL Server</Value></Data><Data><Key>HelpLink.ProdVer</Key><Value>13.00.4001</Value></Data><Data><Key>HelpLink.EvtSrc</Key><Value>MSSQLServer</Value></Data><Data><Key>HelpLink.EvtID</Key><Value>207</Value></Data><Data><Key>HelpLink.BaseHelpUrl</Key><Value>http://go.microsoft.com/fwlink</Value></Data><Data><Key>HelpLink.LinkId</Key><Value>20476</Value></Data></DataItems></Exception></TraceRecord>


Надеюсь, этого достаточно, чтобы идти дальше. Это мой первый раз, когда я пишу в vb.net и sql.

Пожалуйста, дайте мне знать, если у вас возникнут какие-либо вопросы.

Что я уже пробовал:

Я проверил синтаксис на обоих. Он прекрасно работает при использовании штрих-кода для поиска его через SQL. Единственное отличие от этого кода заключается в том, что его нужно вытащить из button1.text для этой конкретной формы.

3 Ответов

Рейтинг:
2

Jochen Arndt

Вы должны цитировать строковые значения в командах SQL:

Form1.cmd = New SqlClient.SqlCommand("SELECT * FROM Inventory WHERE [ItemDescription] ='" + Form1.itemdesc + "'", Form1.sqlConnection1)
В противном случае они рассматриваются как имена полей или команды SQL.

Этого не произошло бы при использовании параметризованных запросов, как это было предложено OrginalGriff в его решении.

Сделайте это так, как он предлагает, вместо того чтобы исправлять свой код с помощью приведенного выше фрагмента кода. Единственная цель этого поста - объяснить, что приводит к сообщению об ошибке.


Jennifer Paige Jones

Спасибо.

Рейтинг:
1

Dave Kreskowiak

Во - первых, вам не нужно все время вводить "Form1", если этот код является частью класса Form1.

Затем запуск кода под отладчиком остановит код в строке, которая вызвала исключение. Выделенная вами строка не может быть той, которая ее бросила, потому что она нигде не упоминает "кружки", и вы, похоже, не добавили никаких параметров к объекту SqlCommand.


Jennifer Paige Jones

"Кружки" было вытянуто из текста на кнопке. Я закрепил его там, где он работает. У меня есть около 10 форм, с которыми я работаю, поэтому я вытаскиваю определенные переменные из формы 1, которые я считаю публичными. Если есть другой способ, пожалуйста, дайте мне знать. Это мой первый раз, когда я использую visual basic или любой другой подобный код.

Спасибо.

Рейтинг:
0

OriginalGriff

Просто: не делай этого так. Никогда не объединяйте строки для построения команды SQL. Это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных. Вместо этого всегда используйте параметризованные запросы.

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:

SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?


Есть масса других вещей, которые здесь плохо сделаны: как уже упоминал Дэйв, использование Form1 все время-плохая идея, как и использование общего командного объекта, магических чисел в вашем доступе к данным считывателя, которые вы вообще не проверяете, возвращаются ли какие-либо данные ... В принципе, откуда бы вы ни скопировали этот код, он идиот, который ничего не знает о том, как правильно кодировать, и вам было бы гораздо лучше просто удалить его "код" и начать все сначала с нуля.

Это параметризованный запрос, выполненный правильно:
Using con As New SqlConnection(strConnect)
	con.Open()
	Using cmd As New SqlCommand("SELECT iD, description FROM myTable WHERE ProductName = @PRODNAME", con)
        cmd.Parameters.AddWithValue("@PRODNAME", itemdesc)
		Using reader As SqlDataReader = cmd.ExecuteReader()
			While reader.Read()
				Dim id__1 As Integer = CInt(reader("iD"))
				Dim desc As String = DirectCast(reader("description"), String)
				Console.WriteLine("ID: {0}" & vbLf & "    {1}", iD, desc)
			End While
		End Using
	End Using
End Using
Теперь используйте этот шаблон во всем вашем приложении - или потеряйте свою базу данных ...


Jennifer Paige Jones

Это мой первый раз, когда я использую что-то вроде Visual Basic, и это POS-система. Обычно я привык использовать Matlab для математического кодирования, поэтому большая часть моего кода основана на том, что я могу найти в интернете или из материалов Matlab, поэтому мне жаль, что он не соответствует требованиям. У меня есть около 10 различных форм, и мне сказали, что я могу иметь публично разделяемые ценности, но я должен называть их из другой формы. Так что я тот самый идиот, о котором вы упомянули, но я думаю, что для моего первого кодирования на visual basic, самостоятельно, только с помощью интернета, я делаю хорошую работу. Мы все должны с чего-то начать.

Теперь к настоящему ответу, я не знал, что это было так. Я исправил его так, как предложил Йохен Арндт из приведенного ниже решения, но как только весь код будет запущен и запущен, я буду искать способы улучшить свою программу в целом. Запрос состоит только из примерно 30-40 вещей, и моя резервная копия в настоящее время представляет собой файл excel.

Это (даже не) Версия 1, и я уверен, что в моем будущем будет еще много версий. Я с нетерпением жду возможности узнать больше и использовать его в своей повседневной жизни.

Спасибо.