How to use Function VB.NET Insert To Database? - vb.net

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).

Related

How to split a joined column into its seperate columns and use the data? (VB.Net + SQL Management Studio)

This is gonna be somewhat tricky to explain but I'll try to break it down. Note that this is created using VB.Net 2003.
I have a Web page which requires user to input data to save into SQL. They are required to fill in:
Course: {Select via drop-down table} \\ Variable name = Crse
Emp No: {Manually type the number} \\ Variable name = Emp
For the drop down list for Course, the data is obtained from an SQL table 'Course', with the columns:
| Course Code | Course Title |
Once input complete, I can then save the entry into my Emp_Course table in SQL using the query:
Dim updateState As String = "insert into EMP_COURSE" _
& "(Employee_No, CourseCode)" _
& "values('" & Emp.Text & "', " _
& "'"Crse.SelectedItem.ToString & "')"
Previously the drop-down list only needed the show Course Code, but now I'm required to add in the Course Title as well. Another thing to point out is that the Course Code has no fixed length.
Drop-down list sample:
Before:
A001
BX003
After:
A001 - Course A
BX003 - Course BX
Meaning I have to change the logic in populating the drop-down list:
Dim list As New SqlCommand("select CourseCode + ' - ' " _
& "+ CourseTitle as Course from [SQL].[dbo].[Course] " _
& "order by CourseCode", SQLDB)
Now comes my main issue, when I want to save my entry, the program obviously gives an error because the SQL still refers to the Course Code only, while my drop-down list is a Code + Description hybrid.
So since now I've made my course selection, how am I supposed to add to my SQL to update Emp_Course table to tell it to select the Course Code part of my hybrid selection?
I would just go to the Course table and just add a new Code + Title column and refer to that, but I have no authority to modify it and need to work around it.
Any other alternatives I can use?
Dim arr As String() = Crse.SelectedItem.ToString().Split(New Char() {"-"c})
Dim courseCode AS String = Trim(arr(0))
Dim updateState As String = "insert into EMP_COURSE" _
& "(Employee_No, CourseCode)" _
& "values('" & Emp.Text & "', " _
& "'"courseCode & "')"
Comments and explanations in line.
Imports System.Data.SqlClient
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
Crse.DataSource = CreateDataSource()
'Course is the concatenated string returned from
'the database containing the CourseCode and the CourseTitle
Crse.DataTextField = "Course"
Crse.DataValueField = "CourseCode"
Crse.DataBind()
Crse.SelectedIndex = 0
End If
End Sub
Protected Function CreateDataSource() As DataTable
Dim dt As New DataTable
Using SQLDB As New SqlConnection("Your connection string")
'This selects the CourseCode as a separate column and the string called Course
'containing the CourseCode and the CourseTitle
Using cmd As New SqlCommand("select CourseCode, CourseCode + ' - ' + CourseTitle as Course from [SQL].[dbo].[Course] order by CourseCode", SQLDB)
SQLDB.Open()
dt.Load(cmd.ExecuteReader)
End Using
End Using
Return dt
End Function
Protected Sub UpdateDatabase()
Using SQLDB As New SqlConnection("Your connection string")
Using cmd As New SqlCommand("insert into EMP_COURSE (Employee_No, CourseCode) values(#EmpNo, #CourseCode);", SQLDB)
'I guessed at the SqlDbType. Check the database for the real data types.
cmd.Parameters.Add("EmpNo", SqlDbType.Int).Value = CInt(Emp.Text)
'Always use parameters to prevent SQL injection
'The SelectedValue will return the CourseCode
cmd.Parameters.Add("#CourseCode", SqlDbType.VarChar).Value = Crse.SelectedValue
SQLDB.Open()
cmd.ExecuteNonQuery()
End Using
End Using
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
UpdateDatabase()
End Sub
End Class
Split the value and get the course code as in the following code. Hope it helps.
Dim Str = Crse.SelectedItem.ToString
Dim strArr() As String
strArr = Str.Split(CType("-", Char()))
Dim CourseCode As String = strArr(0).Trim

Inserting data into database (sqlexception) not working

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.

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

Can't figure out what's wrong when trying to update a database entry

I can't figure out why updating my database entries wont work. Sometimes it tells me there is a syntax error, and other times when I try to delete an entry after trying an update it tells me that the connection was not closed. I'm not that familiar with SQL so any help would be appreciated.
Public Shared Property filename As String
Private dbConnection As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=IT_Checkout.accdb")
Private dbAdapter As OleDbDataAdapter
Private dbDataset As DataSet
Public Function deleteReport(ByVal rID As String,
ByRef msg As String) As Boolean
Dim sql As String
sql = "DELETE FROM Reports WHERE RID = '" & rID & "'"
If do_command(sql, msg) = False Then
Return False
End If
If File.Exists(My.Application.Info.DirectoryPath & "\reports\" & rID & ".dat") Then
My.Computer.FileSystem.DeleteFile(My.Application.Info.DirectoryPath & "\reports\" & rID & ".dat")
End If
Return True
End Function
Public Function updateReport(ByVal r As Report,
ByRef msg As String) As Boolean
Dim sql As String = "UPDATE Reports SET Name='" & r.name & "', Date='" & r.outDate & "', Notes='" & r.notes & "', Archived='" & r.archived.ToString & "' WHERE RID='" & r.getID & "'"
Return do_command(sql, msg)
End Function
Public Function do_command(ByVal sql As String,
ByRef msg As String) As Boolean
Dim command As OleDbCommand
Try
dbConnection.Open()
command = New OleDbCommand(sql, dbConnection)
command.ExecuteNonQuery()
dbConnection.Close()
Return True
Catch ex As Exception
msg = "From Command: " & ex.Message
Return False
End Try
End Function
If any of your values contain apostrophes your syntax will be wrong - you should use parameters instead of concatenating SQL:
Dim sql As String = "UPDATE Reports SET [Name]=?, [Date]=?, Notes=?, Archived=? WHERE RID=?"
command = New OleDbCommand(sql, dbConnection)
command.Parameters.Add("Name").Value = r.name
command.Parameters.Add("Date").Value = r.outDate
command.Parameters.Add("Notes").Value = r.notes
command.Parameters.Add("Archived").Value = r.archived
command.Parameters.Add("RID").Value = r.getID
command.ExecuteNonQuery()
dbConnection.Close()
You should also not share a single connection object - connections are pooled by .NET and are cheap to create.

easiest way to add a SQL column through VB

What i want to do is first check if a certain column already exists in a table and if not add it. I want to implement this through visual basic. If somebody took a little time to comment and briefly explain each step i would greatly appreciate it.
There are two ways to determine if a column exists: either try to use it and catch the error if it doesn't exist, or read the metadata from the database see SQL Server: Extract Table Meta-Data (description, fields and their data types)
Once you know that you need to add the column you use the ALTER TABLE command to add the column to the table.
Here is vb.net script to check if column exist, if not, create it..
''' summary
''' Checks to see if a table exists in Database or not.
'''
''' Table name to check
''' Connection String to connect to
''' Works with Access or SQL
'''
Public Function DoesTableExist(ByVal tblName As String, ByVal cnnStr As String) As Boolean
' For Access Connection String,
' use "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &
' accessFilePathAndName
' Open connection to the database
Dim dbConn As New OleDbConnection(cnnStr)
dbConn.Open()
' Specify restriction to get table definition schema
' For reference on GetSchema see:
' http://msdn2.microsoft.com/en-us/library/ms254934(VS.80).aspx
Dim restrictions(3) As String
restrictions(2) = tblName
Dim dbTbl As DataTable = dbConn.GetSchema("Tables", restrictions)
If dbTbl.Rows.Count = 0 Then
'Table does not exist
DoesTableExist = False
Else
'Table exists
DoesTableExist = True
End If
dbTbl.Dispose()
dbConn.Close()
dbConn.Dispose()
End Function
'''
''' Checks to see if a field exists in table or not.
'''
''' Table name to check in
''' Field name to check
''' Connection String to connect to
'''
'''
Public Function DoesFieldExist(ByVal tblName As String, _
ByVal fldName As String, _
ByVal cnnStr As String) As Boolean
' For Access Connection String,
' use "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" &
' accessFilePathAndName
' Open connection to the database
Dim dbConn As New OleDbConnection(cnnStr)
dbConn.Open()
Dim dbTbl As New DataTable
' Get the table definition loaded in a table adapter
Dim strSql As String = "Select TOP 1 * from " & tblName
Dim dbAdapater As New OleDbDataAdapter(strSql, dbConn)
dbAdapater.Fill(dbTbl)
' Get the index of the field name
Dim i As Integer = dbTbl.Columns.IndexOf(fldName)
If i = -1 Then
'Field is missing
DoesFieldExist = False
Else
'Field is there
DoesFieldExist = True
End If
dbTbl.Dispose()
dbConn.Close()
dbConn.Dispose()
End Function
Dim connString As String = "Data Source=NameOfMachine\InstanceofSQLServer;Initial Catalog=NameOfDataBase;Integrated Security=True"
Dim MyCol As String = "NameOfColumn"
Dim MyTable As String = "[NameOfTable]" ' or "[Name Of Table]" use brackets if table name contains spaces or other illegal Characters
Dim MySql As String = "IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS" & vbCrLf &
"WHERE TABLE_NAME = '" & MyTable & "' AND COLUMN_NAME = '" & MyCol & "')" & vbCrLf &
"BEGIN" & vbCrLf &
"ALTER TABLE [dbo]." & MyTable & " ADD" & vbCrLf & "[" & MyCol & "] INT NULL ;" & vbCrLf & "END"
Try
' MsgBox(MySql)- this msg box shows the Query so I can check for errors- Not required for code.
Dim dbConn = New SqlConnection(connString)' Note ConnString must be declared in the form class or within this Sub. Connstring is your connection string
Dim dbCmd = New SqlCommand(MySql, dbConn)
dbConn.Open()
dbCmd.ExecuteNonQuery()
'MessageBox.Show("Ready To Load Addendums")
dbConn.Close()
Catch ex As Exception
MsgBox("We've encountered an error;" & vbCrLf & ex.Message)
End Try