Inserting data into database (sqlexception) not working - vb.net

I'm Trying to take data entered by the user from the form view and insert it to the table in a database
The problem is that whenever the compiler reach the Rtype variable to store its value it gives me this error:
I know what the error means but i simply can't get it to work .
The following is my code in the class Form1
Imports System.Data.SqlClient
Public Class Form1`
Private Sub newBtn_Click(sender As Object, e As EventArgs) Handles BtnNwRoom.Click
Dim obj As New Hotl()
Dim selectedItem As Object
selectedItem = hotelCombobox.SelectedItem()
If (obj.addnew(CInt(Me.roomNum.Text), CInt(selectedItem), Me.roomType.Text, Me.price.Text) = False) Then
MsgBox(" no record is added, Try again later")
End If
End Sub
End class
This is the add new function :
Public Function addnew(ByVal roomNo As Integer, ByVal hotelNo As String, ByVal RoomType As String, ByVal price As Integer) As Boolean
Dim sqlstmnt = "insert into Room (roomNo,hotelNo,RoomType,price) values( " & roomNo & " , " & hotelNo & " , " & RoomType & " , " & price & ")"
MsgBox(sqlstmnt)
conn = ConNew()
'''''''''''''''''''''''''''''' Execute Reader
''''''''''''''''''''''''''''''''''''''''''''''
Dim command As New SqlCommand(sqlstmnt, conn)
If command.ExecuteNonQuery() = 1 Then
MessageBox.Show("insertion Succeded")
Return True
Else
Return False
End If
End Function

As Tim said, use parameterized queries instead.
But, the main cause of your issue is here:
RoomType As String
Dim sqlstmnt = "insert into Room (roomNo,hotelNo,RoomType,price) values( " & roomNo & " , " & hotelNo &
" , " & RoomType & " , " & price & ")"
RoomType is defined as a string, but you have no enclosing apostrophes in the Query (hence it will be interpreted as a numeric or a name, not a string.
So, in this particular case, use this:
Dim sqlstmnt = "insert into Room (roomNo,hotelNo,RoomType,price) values( " & roomNo & " , " & hotelNo &
" , '" & RoomType & "' , " & price & ")"
But to stress the importance of (among other things) security, use parameterized questions instead and not raw user input directly in the SQL Query.
And just to clarify, here's an example WITH a parameterized Query:
Public Function addnew(ByVal roomNo As Integer, ByVal hotelNo As String, ByVal RoomType As String, ByVal price As Integer) As Boolean
Dim sqlstmnt As String = "INSERT INTO ROOM (roomNo,hotelNo,RoomType,price) VALUES(#roomNo, #hotelNo, #RoomType, #price)"
MsgBox(sqlstmnt)
conn = ConNew()
'''''''''''''''''''''''''''''' Execute Reader
''''''''''''''''''''''''''''''''''''''''''''''
Dim command As New SqlCommand(sqlstmnt, conn)
command.Parameters.Add("#roomNo",SqlDbType.Int).Value = roomNo
command.Parameters.Add("#hotelNo",SqlDbType.Int).Value = hotelNo
command.Parameters.Add("#RoomType",SqlDbType.NVarChar,50).Value = RoomType
command.Parameters.Add("#price",SqlDbType.Int).Value = price
If command.ExecuteNonQuery() = 1 Then
MessageBox.Show("insertion Succeded")
Return True
Else
Return False
End If
End Function
Using this code you're protected against SQL Injections and won't have to run into unforseen problems for using reserved Words etc.

Related

SQL Result to Global Variable

Within my MDIParent Me_Load I have an SQL query that returns user information based upon Windows ID. This works well, however I'd really like to move this logic out into perhaps a module and assign each value in the db to a global variable to be used elsewhere. I'd like to be able to access the contact_id in any child form of the parent MDI. I'm used to PHP where I'd just assign it to a session variable that I could reference anywhere.
This is my current SQL Code
Dim sql_query As String
Dim errorMessages As New StringBuilder()
Dim cnn = ConfigurationManager.ConnectionStrings("sql_connection_string").ConnectionString
Dim adapter As SqlDataAdapter
Dim ds As New DataTable()
Dim User_ID As String
Dim User_First_Name As String
Dim User_Last_Name As String
Dim User_Contact_CD As String
Dim User_Login As String
sql_query = "SELECT Contact_ID, First_Name_CH, Last_Name_CH, Contact_CD, Login_VC FROM [Worktool].[dbo].[vwEmployees_T] WHERE Login_VC = '" & username & "'"
Using connection As New SqlConnection(cnn)
Try
If connection.State = ConnectionState.Closed Then connection.Open()
adapter = New SqlDataAdapter(sql_query, connection)
adapter.Fill(ds)
User_ID = ds.Rows(0)("Contact_ID").ToString()
User_First_Name = ds.Rows(0)("First_Name_CH").ToString()
User_Last_Name = ds.Rows(0)("Last_Name_CH").ToString()
User_Contact_CD = ds.Rows(0)("Contact_CD").ToString()
User_Login = ds.Rows(0)("Login_VC").ToString()
connection.Close()
Catch ex As SqlException
MsgBox("Sorry, there was an issue with the connection. Please try again ! ")
Dim i As Integer
For i = 0 To ex.Errors.Count - 1
errorMessages.Append("Index #" & i.ToString() & ControlChars.NewLine _
& "Message: " & ex.Errors(i).Message & ControlChars.NewLine _
& "LineNumber: " & ex.Errors(i).LineNumber & ControlChars.NewLine _
& "Source: " & ex.Errors(i).Source & ControlChars.NewLine _
& "Procedure: " & ex.Errors(i).Procedure & ControlChars.NewLine)
Next i
MsgBox(errorMessages.ToString())
End Try
End Using
'Assign messages
main_window_welcome.Text = "Welcome back, " & Replace(User_First_Name, " ", "") & " " & Replace(User_Last_Name, " ", "")
variable username is
Public username = Environ$("Username")
You've declared the 4 variables in the class and they are private to that class. At this point your code works. Hilight those 4 variable declarations and Cut them. Your code shows errors because you just removed the declarations.
Add a module to your solution (name it what you want)
paste the declarations into the module body.
change the Dim to Public.
Your errors disappear.
Your variables are now public and available throughout your solution.

Syntax Error with UPDATE command in SQL

Does anything look wrong with this statement? I can't find anything wrong with it...
UPDATE AccountInfo
SET First Name = 'Test', Last Name = 'Account', Street = 'Street', State = 'State', ZipCode = 55555
WHERE id = 1
I'm writing a VB program, and I'm implementing an edit feature. This is the problem code.
Public Function updateAccountInfo(ByVal cp As CPerson, ByVal fName As String, ByVal lName As String, ByVal address As String, ByVal state As String, ByVal zip As Integer) As Boolean
Dim sql, sql2 As String
sql = "UPDATE AccountInfo SET First Name = '" & fName & "', Last Name = '" & lName & "', Street = '" & address & _
"', State = '" & state & "', ZipCode = " & zip & " WHERE id = " & cp.returnIDOnlyNumber
sql2 = "UPDATE Accounts SET First Name = '" & fName & "', Last Name = '" & lName & "' WHERE id = " & cp.returnIDOnlyNumber
Return do_command(sql, sql2)
End Function
Private Function do_command(ByVal sql As String, ByVal sql2 As String) As Boolean
Dim command As OleDbCommand
Try
conn.Open()
command = New OleDbCommand(sql, conn)
command.ExecuteNonQuery()
conn.Close()
conn.Open()
command = New OleDbCommand(sql2, conn)
command.ExecuteNonQuery()
conn.Close()
Return True
Catch ex As Exception
Return False
End Try
End Function
Yes, you have space in the names. If you really have them, then you need to escape them, perhaps with square braces:
UPDATE AccountInfo
SET [First Name] = 'Test',
[Last Name] = 'Account',
Street = 'Street',
State = 'State',
ZipCode = '55555'
WHERE id = 1;
It is better to have names with no spaces. Also, the zip code should be stored as a string, not a number, otherwise you will lose leading zeros.

ExecuteNonQuery() won't work for INSERT function

First of all, I'm not a professional programmer. So there are some big faults possible in my program!
The problem is:
I linked my WPF file in visual express with a MS Access database (format 2003). Whenever I try to run the following (sorry for the dutch code):
Public Sub ToevoegenPersoon(voornaam As String, achternaam As String, mailadres As String, geboortedatum As Date, klantennummer As Integer, specialeCategorie As String)
Dim opdracht As OleDbCommand
Dim sqlOpdracht As String
sqlOpdracht = "INSERT INTO Klant (Voornaam, achternaam, mailadres, geboortedatum, klantennummer, specialeCategorie)" & _
"VALUES (" & Chr(34) & "" & voornaam & "" & Chr(34) & "," & Chr(34) & "" & achternaam & "" & Chr(34) & "," & Chr(34) & "" & _
mailadres & "" & Chr(34) & "," & Convert.ToString(geboortedatum) & "," & Convert.ToString(klantennummer) & "," & Chr(34) & "" & specialeCategorie & "" & Chr(34) & ")"
opdracht = New OleDbCommand(sqlOpdracht, connectie)
Debug.WriteLine(sqlOpdracht)
MsgBox(sqlOpdracht)
opdracht.Connection.Open()
opdracht.ExecuteNonQuery()
opdracht.Connection.Close()
End Sub
my program always has an error for the ExecuteNonQuery() function. This function is used for the following event:
Private Sub btnKlantToevoegen_Click(sender As Object, e As RoutedEventArgs) Handles btnKlantToevoegen.Click
Dim achternaam As String = boxVoornaam.Text
Dim voornaam As String = boxAchternaam.Text
Dim emailadres As String = boxEmailadres.Text
Dim geboortedatum As Date = GeboortedatumSelectie.SelectedDate
Dim klantennummer As Integer = 5
Dim specialeCategorie As String = "Jeugd"
Try
database.ToevoegenPersoon(voornaam, achternaam, emailadres, geboortedatum, klantennummer, specialeCategorie)
Catch ex As Exception
End Try
boxAchternaam.Clear()
boxVoornaam.Clear()
boxEmailadres.Clear()
End Sub
At the top, I stated the following to connect MS Access database with Visual express:
Private connectiestring As String = My.Settings.Database_Drijkoningen_Konings1ConnectionString
Private connectie As OleDbConnection
connectie = New OleDbConnection(connectiestring)
When running this program, the executenonquery() gives an error. And I have no clue whatsoever what it can be. Anybody who does?
Thanks in advance
Jeroen
Not sure if this could resolve your problem. I don't know the error message. However I will show a simple parameterized query that probably could help a lot
Public Sub ToevoegenPersoon(voornaam As String, achternaam As String, mailadres As String, geboortedatum As Date, klantennummer As Integer, specialeCategorie As String)
Dim opdracht As OleDbCommand
Dim sqlOpdracht As String
sqlOpdracht = "INSERT INTO Klant (Voornaam, achternaam, mailadres, " & _
"geboortedatum, klantennummer, specialeCategorie) " & _
"VALUES (?,?,?,?,?,?)"
opdracht = New OleDbCommand(sqlOpdracht, connectie)
opdracht.Parameters.AddWithValue("#p1", voornaam)
opdracht.Parameters.AddWithValue("#p2", achternaam)
opdracht.Parameters.AddWithValue("#p3", mailadres)
opdracht.Parameters.AddWithValue("#p4", Convert.ToString(geboortedatum))
opdracht.Parameters.AddWithValue("#p5", Convert.ToString(klantennummer))
opdracht.Parameters.AddWithValue("#p6", specialeCategorie)
opdracht.Connection.Open()
opdracht.ExecuteNonQuery()
opdracht.Connection.Close()
End Sub
Now, with a parameterized query there is no more concatenations on the command text and this alone will remove any possibility to forget some quote or comma between value. (Of course this removes also the Sql Injection problem and the parsing of strings that contain special characters)
There is still a problem to be resolved. The 4th and 5th parameter receive a string value. This requires the underlying field on the datatable to be a string field and not a DateTime. If this is not the case then you need to pass (as parameter value) just the date value

If or case statement based on radio button click

I am trying to find a way to run some code based on the selection of a radio button. I have several radio buttons in a groupbox which will run different code based on there selection. Now, being a fairly new user to VB.NET, I am struggling to correctly code this.
Would I be better to use an IF statement or a SELECT CASE statement. I have tried using a flag set as a boolean to indicate if button1 is selected, set flag = true. That is as far as I have got. I am using CheckedChanged event to handle to event changes. I have included some code and would be grateful if someone could start me off. Many thanks.
Private Sub rdbBoxReturn_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rdbBoxReturn.CheckedChanged
'code goes here
flagBoxReturn = True
End Sub
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
Try
If flagBoxReturn = True Then
MessageBox.Show(CStr(flagBoxReturn))
Return
Else
DBConnection.connect()
sql = "SELECT MAX([Id]) from Request Boxes WHERE Customer = '" & cmbCustomer.Text & "' "
'MessageBox.Show(cmbCustomer.Text)
'sql = "INSERT INTO [Requests] ("")"
'Dim sql As String = "SELECT * from Boxes WHERE Customer = ? AND Status = 'i'"
Dim cmd As New OleDb.OleDbCommand
Dim id As String
Dim requestor As String = "DEMO"
Dim intake As String = "I"
Dim status As String = "O"
'cmd.Parameters.AddWithValue("#p1", cmbCustomer.Text)
cmd.CommandText = sql
cmd.Connection = oledbCnn
dr = cmd.ExecuteReader
'lvSelectRequestItems.Items.Clear()
While dr.Read()
id = CStr(CInt(dr.Item(0).ToString))
id = String.Format("{0:D6}", (Convert.ToInt32(id) + 1))
'id = CStr(CDbl(id) + 1)
End While
MessageBox.Show(CStr(id))
dr.Close()
sql = "INSERT INTO [Request Boxes] ([Request no], Customer, Dept, [Type], [Service level], [Date-time received], [Received by], [Date-time due], Quantity, [Cust requestor], Status ) " &
"VALUES ('" & id & "', '" & cmbCustomer.Text.ToUpper & "', '" & cmbDept.Text & "', '" & intake.ToString & "', '" & rbServiceLevel.ToString & "', '" & dtpDateReceived.Value & "', '" & requestor.ToString & "', '" & dtpDateDue.Value & "', '" & txtBoxQuantity.Text & "', '" & requestor.ToString & "', '" & status & "')"
cmd.CommandText = sql
cmd.ExecuteNonQuery()
cmd.Dispose()
oledbCnn.Close()
flagBoxReturn = False
MessageBox.Show("Your record number: " & id & " Was entered successfully")
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
How about something like this...
Public Enum SaveOption As Int32
DoNothing = 0
DoSomething = 1 ' Obviously rename this to something that makes sense in your situation.
End Enum
Public Function GetSaveOption() As SaveOption
Dim result As SaveOption = SaveOption.DoNothing
If rdbBoxReturn.Checked Then
result = DoSomething
End If
' Add as many if statements her to cover all your radio buttons.
Return result
End Function
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
Select Case GetSaveOption
Case SaveOption.DoNothing
Exit Sub
Case SaveOption.DoSomething
' Your save code here
End Select
End Sub
This method makes your code more readable by converting UI element states into program states.
Switch statement is better if the number of comparisons is small
if you had a radio button list control, that would be much better as in that case
switch statement can be passed the index variable (SelectedIndex property of the radio
button list) but that control is available in web forms, or can be available in win forms
if you find some free user/custom control etc.
so in your case, better to use if else statements

How to use Function VB.NET Insert To Database?

i using function with vb.net. i'm query sql to datagridview and insert data from datagridview to Databse By function.
But Error in function: The name 'EXHBK13004' is not permitted in this context. Only constants, expressions, or variables allowed here. Column names are not permitted.
i want using function with insert to database.
Table Clother
Name Type
No (PK) int
Code nvarchar(12)
RClother int
CIDetail int
PO nvarchar(50)
Code (Button Save)
Private Sub btSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btSave.Click
For i As Integer = 0 To DgvItem.Rows.Count - 1
sendPDTStatus = FInsertClother(CStr(DgvItem.Rows(i).Cells(0).Value), CInt(DgvItem.Rows(i).Cells(1).Value), CInt(DgvItem.Rows(i).Cells(2).Value), _
DgvItem.Rows(i).Cells(3).Value)
Next
End Sub
Code Function
Public Function FInsertClother(ByVal Code As String, ByVal RClother As Integer, ByVal CIDetail As Integer, ByVal PO As String)
Dim Tr As SqlTransaction
Dim sqlCom As New SqlCommand
Dim sqlInsert As String
Dim ReturnValue As Integer
Tr = Conn.BeginTransaction
sqlCom.Connection = Conn
sqlInsert = "INSERT INTO Clother "
sqlInsert &= "(Code,RClother,CIDetail,PO) "
sqlInsert &= "VALUES(" & Code & "," & RClother & "," & CIDetail & "," & PO & ")"
sqlCom.Transaction = Tr
sqlCom.CommandText = sqlInsert
sqlCom.CommandType = CommandType.Text
ReturnValue = sqlCom.ExecuteScalar << Line Error
If ReturnValue = 0 Then
Tr.Commit()
Else
Tr.Rollback()
End If
Return ReturnValue
End Function
I try Debug this result
Name Value
sqlCom.CommandText "INSERT INTO Clother (Code,RClother,CIDetail,PO) VALUES(050030543003,5022,30543,EXHBK13004/3)"
sqlInsert "INSERT INTO Clother (Code,RClother,CIDetail,PO) VALUES(050030543003,5022,30543,EXHBK13004/3)"
Only field "PO" don't insert to database.
Thanks you for your time. :))
First of all I would remove the string concatenation and use a parameterized query to avoid parsing problems and Sql Injections (In your code you have passed two strings without using quotes and this will surely fail the insert because string fields require a quote delimiter)
Then I remove also the Transaction because, as it stands now the loop executes and confirms a single command for each row.
Also you seems to have a global connection object and this is a bad practice, you should open the connection and close it as soon as possible without keeping it open for the lifetime of your application.
Public Function FInsertClother(ByVal Code As String, ByVal RClother As Integer, ByVal CIDetail As Integer, ByVal PO As String)
Dim sqlInsert As String
Dim ReturnValue As Integer
sqlInsert = "INSERT INTO Clother " & _
"(Code,RClother,CIDetail,PO) " & _
"VALUES(#code, #clot, #id, #po)"
Using sqlCom = new SqlCommand(sqlInsert, conn)
sqlCom.Connection = Conn
sqlCom.Parameters.AddWithValue("#code",Code)
sqlCom.Parameters.AddWithValue("#clot", RClother)
sqlCom.Parameters.AddWithValue("#id",CIDetail)
sqlCom.Parameters.AddWithValue("#po",PO)
ReturnValue = sqlCom.ExecuteNonQuery
Return ReturnValue
End Using
End Function
A very useful enhancements would be to open the connection on the button click and pass it to this function. So when you have finished to loop over the rows you could close the connection via a Using Statement
You need to put the string values in quotes.
sqlInsert &= "VALUES('" & Code & "'," & RClother & "," & CIDetail & ",'" & PO & "')"
That said, you should not build a query string using concatenation. This makes your query subject to a SQL Injection attack. Instead, you should use a parametrized query. (as Steve shows in his answer).