Path to Access Database in Visual Studio 2015 - vb.net

I'm working on a project in VB.NET, using Visual Studio 2015. My goal is that the user can create contacts, which the program puts in an Access database and lists in a DataGridView. I am using the following connection string:
Provider=Microsoft.ACE.OLEDB.12.0; Data Source = C:\Users\Jacob\Documents\Visual Studio 2015\Projects\Accustomer\Accustomer\Global.accdb
This works fine when I publish it to my own PC, but the problem is that when I try to run it on another PC, it does not work because of the data source path not existing on that PC(pretty logic). I have tried to use "Data Source = Global.accdb". This works for displaying the data, but not for implementing the data into the database. Is there any way that the program recognizes the database without implementing the full path to the database?

As said in comments by krish,you should "build" your own path...so everytime you run you programm on another machine YOUR CODE creates the path using the right parameters.
You dont give a fix path, your code creates the right one for every machine it runs on. So the filename can be hardcoded, but the path to it should be "flexible".
In krish example [projectPath] and [db] are variables, that contain the right values depending on the PC.
$"Provider=Microsoft.ACE.OLEDB.12.0; Data Source = {projectPath}\{db}\Global.accdb"

What's presented below has already been mentioned and is correct, here I'm simply showing a full working example.
I created a class named Operations with a public (could be private) variable to create a connection string where the connection points to Global.accdb in the same folder as the application's executable file. If the database were a folder below you would add that path in the IO.Path.Combine right before the hard coded string. Note I used AppDomain.CurrentDomain.BaseDirectory as Application.StartupPath is not always available in other types of projects.
Create the connection string.
Private Builder As New OleDbConnectionStringBuilder With
{
.Provider = "Microsoft.ACE.OLEDB.12.0",
.DataSource = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Global.accdb")
}
Now here is the full code which I wrote for replying to questions for constructing not only the connection but for read/add/update and delete encapsulated into a single class for simplicity.
Public Class Operations
''' <summary>
''' Points to Global.accdb in the same folder as the application's
''' executable file
''' </summary>
Private Builder As New OleDbConnectionStringBuilder With
{
.Provider = "Microsoft.ACE.OLEDB.12.0",
.DataSource = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Global.accdb")
}
Public Sub New()
If Not IO.File.Exists(Builder.DataSource) Then
Throw New IO.FileNotFoundException("Failed to find application's database")
End If
End Sub
Public Sub GetCustomerData()
Dim DataTable As New DataTable
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText =
<SQL>
SELECT Identifier, ContactTitle, Country, CompanyName
FROM Customers
ORDER BY CompanyName ASC
</SQL>.Value
cn.Open()
DataTable.Load(cmd.ExecuteReader)
End Using
End Using
End Sub
Public Function AddNewRow(ByVal Name As String, ByVal Contact As String, ByRef Identfier As Integer) As Boolean
Dim Success As Boolean = True
Dim Affected As Integer = 0
Try
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText =
<SQL>
INSERT INTO Customer
(
CompanyName,
ContactName
)
Values
(
#CompanyName,
#ContactName
)
</SQL>.Value
cmd.Parameters.AddWithValue("#CompanyName", Name)
cmd.Parameters.AddWithValue("#ContactName", Contact)
cn.Open()
Affected = cmd.ExecuteNonQuery()
If Affected = 1 Then
cmd.CommandText = "Select ##Identity"
Identfier = CInt(cmd.ExecuteScalar)
End If
End Using
End Using
Catch ex As Exception
Success = False
End Try
Return Success
End Function
Public Function UpdateCustomer(ByVal CustomerId As Integer, ByVal Name As String, ByVal Contact As String) As Boolean
Dim Success As Boolean = True
Dim Affected As Integer = 0
Try
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText =
<SQL>
UPDATE Customer
SET CompanyName = #CompanyName, ContactName = #ContactName
WHERE Identifier = #Identifier
</SQL>.Value
cmd.Parameters.AddWithValue("#CompanyName", Name)
cmd.Parameters.AddWithValue("#ContactName", Contact)
cmd.Parameters.AddWithValue("#Identifier", Contact)
cn.Open()
Affected = cmd.ExecuteNonQuery()
If Affected = 1 Then
Success = True
End If
End Using
End Using
Catch ex As Exception
Success = False
End Try
Return Success
End Function
Public Function DeleteCustomer(ByVal CustomerId As Integer) As Boolean
Dim Success As Boolean = True
Dim Affected As Integer = 0
Try
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText = "DELETE FROM Customers WHERE Identifier = #Identifier"
cmd.Parameters.AddWithValue("#Identifier", CustomerId)
cn.Open()
Affected = cmd.ExecuteNonQuery()
If Affected = 1 Then
Success = True
End If
End Using
End Using
Catch ex As Exception
Success = False
End Try
Return Success
End Function
End Class

Related

Database query not returning results from value

I am making a work management system and I am fairly new to Visual Basic.
What I am trying to do is retrieve the name of the employee from the database with the given ID. After that I want this name to be displayed in a Label. After that, he can press the Work Start or Work end buttons.
Here is the code:
Private Function employeeSearchwithID(PersonalNr As String) As String
Dim mitarbeiter As String
Dim r As DataRow
Access.ExecQuery("SELECT [Vorname], [Name] from [TA-Personal] WHERE ([Personal_Nr] = '" & PersonalNr & "');")
'Report and Abort on Erros or no Records found
If NoErros(True) = False Or Access.RecordCount < 1 Then Exit Function
r = Access.DBDT.Rows(0)
'Populate Label with Data
mitarbeiter = r.Item("Vorname") & " " & r.Item("Name")
Return mitarbeiter
End Function
It is used like this:
Private Sub tbxUserInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tbxUserInput.KeyDown
If e.KeyCode = Keys.Enter Then 'employeeIDnumbersSelect()
Label5.Text = employeeSearchwithID(tbxUserInput.ToString)
End If
End Sub
So, the plan is to have this program running on a tablet connected to a scanner. Every employee will have a personal card. When they scan the card, I want their names to be displayed. Of course, the card will be with the ID. But I am having trouble with the names: when I give my personal number it comes up as an empty string.
I have a separate DB Module. I learned from a tutorial:
Imports System.Data.OleDb
Public Class DBControl
' DB Connection
Public DBCon As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:\recycle2000.mdb;")
'DB Command
Public DBCmd As OleDbCommand
'DB Data
Public DBDA As OleDbDataAdapter
Public DBDT As DataTable
'Public Myreader As OleDbDataReader = DBCmd.ExecuteReader
'Query Paramaters
Public Params As New List(Of OleDbParameter)
' Query Stats
Public RecordCount As Integer
Public Exception As String
Public Sub ExecQuery(Query As String)
'Reset Query Stats
RecordCount = 0
Exception = ""
Try
'Open a connection
DBCon.Open()
'Create DB Command
DBCmd = New OleDbCommand(Query, DBCon)
' Load params into DB Command
Params.ForEach(Sub(p) DBCmd.Parameters.Add(p))
' Clear params list
Params.Clear()
' Execute command & fill Datatable
DBDT = New DataTable
DBDA = New OleDbDataAdapter(DBCmd)
RecordCount = DBDA.Fill(DBDT)
Catch ex As Exception
Exception = ex.Message
End Try
' Close your connection
If DBCon.State = ConnectionState.Open Then DBCon.Close()
End Sub
' Include query & command params
Public Sub AddParam(Name As String, Value As Object)
Dim NewParam As New OleDbParameter(Name, Value)
Params.Add(NewParam)
End Sub
End Class
Without knowledge of the Access class, I have to recommend a different approach to querying the database. It is important to make sure that the database is not vulnerable to SQL injection, be it deliberate or accidental. The way to do that is to use what are known as SQL parameters: instead of putting the value in the query string, the value is supplied separately.
Private Function EmployeeSearchwithID(personalNr As String) As String
Dim mitarbeiter As String = String.Empty
Dim sql = "SELECT [Vorname], [Name] from [TA-Personal] WHERE [Personal_Nr] = ?;"
Using conn As New OleDbConnection("your connection string"),
cmd As New OleDbCommand(sql, conn)
cmd.Parameters.Add(New OleDbParameter With {.ParameterName = "#PersonalNr",
.OleDbType = OleDbType.VarChar,
.Size = 12,
.Value = personalNr})
conn.Open()
Dim rdr = cmd.ExecuteReader()
If rdr.Read() Then
mitarbeiter = rdr.GetString(0) & " " & rdr.GetString(1)
End If
End Using
Return mitarbeiter
End Function
Private Sub tbxUserInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tbxUserInput.KeyDown
If e.KeyCode = Keys.Enter Then 'employeeIDnumbersSelect()
Dim employeeName = EmployeeSearchwithID(tbxUserInput.Text.Trim())
If String.IsNullOrEmpty(employeeName) Then
MessageBox.Show("Not found.", "Problem", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Else
Label5.Text = employeeName
End If
End If
End Sub
The Using command makes sure that the "unmanaged resources" involved in querying a database are cleaned up afterwards, even if something goes wrong.
You will need to change the value of OleDbType.VarChar and .Size = 12 to match the type and size of that column in the database.
The name of the parameter is only for convenience with OleDb because it is ignored in the actual query, which uses "?" as a placeholder. Please see OleDbCommand.Parameters Property for full information.
If it still does not work, then please enter the ID manually in the tbxUserInput and see if you can make it work that way.
Hang on... tbxUserInput.ToString should be tbxUserInput.Text. But everything else I wrote still applies.

Must declare the scalar variable "#SSTGroupID"

Private Function GetSvcType(ByVal oCommand As OleDbCommand, ByVal SSTGroupID As Integer) As DataTable
Dim sSQL As New StringBuilder
sSQL.AppendLine(" Select SSTServiceTypeID AS ID, SSTServiceTypeName AS Name ")
sSQL.AppendLine(" from fgen_SSTServiceType (nolock) ")
sSQL.AppendLine(" Where 1=1 AND Disabled = 0 ")
sSQL.AppendLine(" AND fgen_SSTServiceType.SSTGroupID = #SSTGroupID ")
oCommand.Parameters.AddWithValue("#SSTGroupID", SSTGroupID)
Return GetDataTable(sSQL.ToString)
End Function
Private Function GetDataTable(ByVal SQL As String) As DataTable
Dim oConn As OleDbConnection = New OleDbConnection(_strConnection)
Dim oCommand As New OleDbCommand("", oConn)
oCommand.Connection.Open()
oCommand.CommandText = SQL
oCommand.Parameters.Clear()
Dim oDataTable As New DataTable
Dim oDataAdapter As New OleDbDataAdapter(oCommand)
oDataAdapter.Fill(oDataTable)
If oDataTable.Rows.Count > 0 Then
GetDataTable = oDataTable
Else
GetDataTable = Nothing
End If
oCommand.Connection.Close()
oCommand.Dispose()
End Function
I've been searching for hours on end and can't seem to find a solution. I need your help please thanks
I've updated my question include the GetDataTable function. Please take a look thanks.
Your command never gets the text from the StringBuilder. So I think the missing link is that you should assign the string you've built to the command text
oCommand.CommandText = sSQL.ToString()
then add the parameter after that
Private Function GetSvcType(ByVal oCommand As OleDbCommand, ByVal SSTGroupID As Integer) As DataTable
Dim sSQL As New StringBuilder()
sSQL.AppendLine(" Select SSTServiceTypeID AS ID, SSTServiceTypeName AS Name ")
sSQL.AppendLine(" from fgen_SSTServiceType (nolock) ")
sSQL.AppendLine(" Where 1=1 AND Disabled = 0 ")
sSQL.AppendLine(" AND fgen_SSTServiceType.SSTGroupID = #SSTGroupID ")
oCommand.CommandText = sSQL.ToString()
oCommand.Parameters.AddWithValue("#SSTGroupID", SSTGroupID)
Return GetDataTable(oCommand.CommandText)
End Function
Alternatively, you may want to use a Using to create a command and dispose it. I'd write it but I don't see your connection so you should look into this answer for an example.
I wasn't sure what the Where 1 = 1 and the (no lock) were doing so I removed them.
The function FillDataTable contains all your database access code which keeps it separate from the User Interface code. Your database objects should be locale so you can control that they are closed and disposed. The Using...End Using block takes care of this even if there is an error. Get rid of any class level variables for commands and connections. Both the command and connection are included; note the comma at the end if the first line of the Using.
You can pass your connection string directly to the constructor of the connection and pass the command text and connection directly to the constructor of the command. Saves having to set these properties individually.
OleDb pays no attention to the name of the parameter, so, the order that the parameter is added to the Parameters collection must match the order that the parameter appears in the command text. In this case, you have only one but just for future reference. It is better to use the Parameters.Add() which includes the database datatype. See http://www.dbdelta.com/addwithvalue-is-evil/
and
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
and another one:
https://dba.stackexchange.com/questions/195937/addwithvalue-performance-and-plan-cache-implications
Here is another
https://andrevdm.blogspot.com/2010/12/parameterised-queriesdont-use.html
Note: I had to guess at the datatype of your parameter. Check your database for the actual type.
Always open your connection at the last possible moment (the line before the .Execute...) and close it as soon as possible (the End Using)
Private Function FillDataTable(GroupID As Long) As DataTable
Dim strSQL = "Select SSTServiceTypeID AS ID, SSTServiceTypeName As Name
From fgen_SSTServiceType
Where Disabled = 0
And SSTGroupID = #SSTGroupID "
Dim dt As New DataTable
Using cn As New OleDbConnection("Your connection string"),
cmd As New OleDbCommand(strSQL, cn)
cmd.Parameters.Add("#SSTGroupID", OleDbType.BigInt).Value = GroupID
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim dt = FillDataTable(7L) 'the L indicates that this is a long,pass the GroupID to the function
DataGridView1.DataSource = dt
End Sub
EDIT
Dim dt = FillDataTable(7L) 'In the button code
And in the Data Access code change Oledb to Sql
Imports System.Data.SqlClient
Class DataAccess
Private Function FillDataTable(GroupID As Long) As DataTable
Dim strSQL = "Select SSTServiceTypeID AS ID, SSTServiceTypeName As Name
From fgen_SSTServiceType
Where Disabled = 0
And SSTGroupID = #SSTGroupID "
Dim dt As New DataTable
Using cn As New SqlConnection("Your connection string"),
cmd As New SqlCommand(strSQL, cn)
cmd.Parameters.Add("#SSTGroupID", SqlDbType.BigInt).Value = GroupID
cn.Open()
dt.Load(cmd.ExecuteReader)
End Using
Return dt
End Function
End Class

Unable to insert values into MS Access database

Can anyone please look at below code and advise what is wrong in this?
I was trying to insert values into an MS Access database. Compiler throws no error but the values are not inserted in table.
Code:
Private Sub btnSignInOK_Click(sender As Object, e As EventArgs) Handles btnSignInOK.Click
uniqid = "1"
Try
Dim ConnSignIn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Resources\DBpPNRGENERATORDATA.accdb;Persist Security Info=True")
Dim CmdSignIn As New OleDb.OleDbCommand
If Not ConnSignIn.State = ConnectionState.Open Then
ConnSignIn.Open()
End If
CmdSignIn.Connection = ConnSignIn
CmdSignIn.CommandText = "DELETE TEMPSIGNIN.* FROM TEMPSIGNIN WHERE IDENTIFIER='" + uniqid + "'"
CmdSignIn.ExecuteNonQuery()
CmdSignIn.CommandText = "INSERT INTO TEMPSIGNIN(IDENTIFIER,EPR,Partition,Host)VALUES('" & uniqid & "','" & tbSigninEPR.Text & "','" & cbSignInPartition.Text & "','" & tbSignInAl.Text & "')"
CmdSignIn.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
The DELETE command is not quite right. You do not need to specify the columns in a command as you are deleting the row not the columns:
DELETE FROM [TableName]
Next you should be using parameters when executing SQL commands. This is to reduce syntax issues but more importantly stops SQL injection. See Bobby Tables for more details on this. I use the ? placeholder within my SQL command when using parameters. I also specify the data type so consider using the OleDbParameter Constructor (String, OleDbType) to add your parameters.
I would also consider implementing Using:
Managed resources are disposed of by the .NET Framework garbage collector (GC) without any extra coding on your part. You do not need a Using block for managed resources. However, you can still use a Using block to force the disposal of a managed resource instead of waiting for the garbage collector.
You could implement a check for the value returned by ExecuteNonQuery() to see if the row was deleted before inserting the new row.
All together your code would look something like this:
uniqid = "1"
Dim rowDeleted As Boolean
Using con As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Resources\DBpPNRGENERATORDATA.accdb;Persist Security Info=True")
Using cmd As New OleDbCommand("DELETE FROM [TEMPSIGNIN] WHERE [IDENTIFIER] = ?", con)
con.Open()
cmd.Parameters.Add("#Id", OleDbType.Integer).Value = uniqid
rowDeleted = cmd.ExecuteNonQuery() = 1
End Using
If rowDeleted Then
Using cmd As New OleDbCommand("INSERT INTO [TEMPSIGNIN] ([IDENTIFIER], [EPR], [Partition], [Host]) VALUES (?, ?, ?, ?)", con)
cmd.Parameters.Add("#Id", OleDbType.[Type]).Value = uniqid
cmd.Parameters.Add("#EPR", OleDbType.[Type]).Value = tbSigninEPR.Text
cmd.Parameters.Add("#Partition", OleDbType.[Type]).Value = cbSignInPartition.Text
cmd.Parameters.Add("#Host", OleDbType.[Type]).Value = tbSignInAl.Text
cmd.ExecuteNonQuery()
End Using
End If
End Using
Note that I have used OleDbType.[Type]. You will want to replace [Type] with the data type you've used on your database.
As mentioned above, your syntax for the DELETE SQL is wrong. So when the database tries to execute it, it fails, so the INSERT never runs. Change the DELETE to:
CmdSignIn.CommandText = "DELETE FROM TEMPSIGNIN WHERE IDENTIFIER='" + uniqid + "'"
Also, you should learn how to use SQL Parameters and not use string concatenation to create a SQL string. Using parameters your DELETE query becomes something like (this is not 100%, it's off the top of my head)
CmdSignIn.CommandText = "DELETE FROM TEMPSIGNIN WHERE IDENTIFIER=#ID"
CmdSignIn.Parameters.Add("#ID", uniqid)
CmdSignIn.ExecuteNonQuery()
Okay, focusing on why there is no exception thrown no matter the syntax used. Are you sure you are targeting the right physical database?
If targeting the correct database, if the database is in Solution Explorer then select the database, select properties, check the property "Copy to Output Directory" the default is Copy Always, if you have this set then on each build the database in the project folder overwrite the database in the app folder directory thus no changes would be there.
Side note:
Going with the recommendations provided so far, here is a pattern to consider. Place all database operations in it's own class. The class below is simple, read, update, add and remove from a MS-Access database table Customers with (for this sample) a primary key, company name and contact name.
Each operation in it's own function with error handling which on failure you can get back the exception (I simply use the exception message for this sample).
A BindingSource is used as this component makes life easier when traversing data bound controls such as TextBoxes and or a DataGridView.
The form code displays data in a DataGridView, there is a button to remove the current record and a button to add a new record (I left out assertion to see if the TextBoxes have data). I used two TextBox controls to get information for inserting records.
Form code
Public Class StackOverFlowForm1
Private Operations As New Sample2
Private bsCustomers As New BindingSource
Private Sub StackOverFlowForm1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim ops As New Sample2
If ops.LoadCustomers Then
bsCustomers.DataSource = ops.CustomersDataTable
DataGridView1.DataSource = bsCustomers
Else
MessageBox.Show($"Failed to load table data{Environment.NewLine}{ops.Exception.Message}")
End If
End Sub
Private Sub cmdDeleteCurrent_Click(sender As Object, e As EventArgs) Handles cmdDeleteCurrent.Click
If bsCustomers.Current IsNot Nothing Then
Dim ops As New Sample2
Dim currentIdentifier As Integer = CType(bsCustomers.Current, DataRowView).Row.Field(Of Integer)("Identifier")
If Not ops.DeleteCustomer(currentIdentifier) Then
MessageBox.Show($"Failed to remove customer: {ops.Exception.Message}")
Else
bsCustomers.RemoveCurrent()
End If
End If
End Sub
Private Sub cmdInsert_Click(sender As Object, e As EventArgs) Handles cmdInsert.Click
Dim ops As New Sample2
Dim newId As Integer = 0
If ops.AddNewRow(txtCompanyName.Text, txtContact.Text, newId) Then
CType(bsCustomers.DataSource, DataTable).Rows.Add(New Object() {newId, txtCompanyName.Text, txtContact.Text})
Else
MessageBox.Show($"Failed to add customer: {ops.Exception.Message}")
End If
End Sub
End Class
Then we have a class for database operations. The database is located in the app folder.
Public Class Sample2
Private Builder As New OleDbConnectionStringBuilder With
{
.Provider = "Microsoft.ACE.OLEDB.12.0",
.DataSource = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Database1.accdb")
}
Private mExceptiom As Exception
''' <summary>
''' Each method when executed, if there is an exception thrown
''' then mException is set and can be read back via Exception property
''' only when a method returns false.
''' </summary>
''' <returns></returns>
Public ReadOnly Property Exception As Exception
Get
Return mExceptiom
End Get
End Property
''' <summary>
''' Container for data read in from a database table
''' </summary>
''' <returns></returns>
Public Property CustomersDataTable As DataTable
Public Function LoadCustomers() As Boolean
If Not IO.File.Exists(Builder.DataSource) Then
Return False
End If
Try
CustomersDataTable = New DataTable
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText = "SELECT Identifier, CompanyName, ContactTitle FROM Customers"
cn.Open()
CustomersDataTable.Load(cmd.ExecuteReader)
CustomersDataTable.DefaultView.Sort = "CompanyName"
CustomersDataTable.Columns("Identifier").ColumnMapping = MappingType.Hidden
End Using
End Using
Return True
Catch ex As Exception
mExceptiom = ex
Return False
End Try
End Function
''' <summary>
''' Delete a customer by their primary key
''' </summary>
''' <param name="CustomerId"></param>
''' <returns></returns>
Public Function DeleteCustomer(ByVal CustomerId As Integer) As Boolean
Dim Success As Boolean = True
Dim Affected As Integer = 0
Try
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText = "DELETE FROM Customers WHERE Identifier = #Identifier"
cmd.Parameters.AddWithValue("#Identifier", CustomerId)
cn.Open()
Affected = cmd.ExecuteNonQuery()
If Affected = 1 Then
Success = True
End If
End Using
End Using
Catch ex As Exception
Success = False
mExceptiom = ex
End Try
Return Success
End Function
Public Function UpdateCustomer(ByVal CustomerId As Integer, ByVal CompanyName As String, ByVal ContactName As String) As Boolean
Dim Success As Boolean = True
Dim Affected As Integer = 0
Try
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText = "UPDATE Customer SET CompanyName = #CompanyName, ContactName = #ContactName WHERE Identifier = #Identifier"
cmd.Parameters.AddWithValue("#CompanyName", CompanyName)
cmd.Parameters.AddWithValue("#ContactName", ContactName)
cmd.Parameters.AddWithValue("#Identifier", ContactName)
cn.Open()
Affected = cmd.ExecuteNonQuery()
If Affected = 1 Then
Success = True
End If
End Using
End Using
Catch ex As Exception
Success = False
mExceptiom = ex
End Try
Return Success
End Function
''' <summary>
''' Add new row, if successful provide the new record's primary key
''' </summary>
''' <param name="Name"></param>
''' <param name="ContactName"></param>
''' <param name="Identfier"></param>
''' <returns></returns>
Public Function AddNewRow(ByVal Name As String, ByVal ContactName As String, ByRef Identfier As Integer) As Boolean
Dim Success As Boolean = True
Try
Using cn As New OleDbConnection With {.ConnectionString = Builder.ConnectionString}
Using cmd As New OleDbCommand With {.Connection = cn}
cmd.CommandText = "INSERT INTO Customers (CompanyName,ContactName) Values(#CompanyName,#ContactName)"
cmd.Parameters.AddWithValue("#CompanyName", Name)
cmd.Parameters.AddWithValue("#ContactName", ContactName)
cn.Open()
Dim Affected As Integer = cmd.ExecuteNonQuery()
If Affected = 1 Then
cmd.CommandText = "Select ##Identity"
Identfier = CInt(cmd.ExecuteScalar)
End If
End Using
End Using
Catch ex As Exception
Success = False
mExceptiom = ex
End Try
Return Success
End Function
End Class

VB: SQL Query return result to textbox

In short, I am working on a program that will add/edit entries to an SQL database.
One of the features for this program is that it, if given the account ID number, will look up the name under that account with that given ID. This is what I am having trouble with.
General Format:
Objective: SQL Query that will return string to textbox
AcctID => field in table with account number
AcctName => field in table with account name
txtbx_accountName => textbox I need the name returned to
NOTE:
This is all nested in a generic Try-Catch statement with error
handling.
This is all inside a Click event handler for a button.
This is all done in Visual Studio 2015
Dim myConn As New SqlConnection
Dim myCmd As New SqlCommand
myConn.ConnectionString = ""
myConn.Open() ' Open the connection
myCmd = myConn.CreateCommand()
' Build the query with the account number as paramter
myCmd.CommandText = "SELECT AcctName FROM DataSetTable WHERE (AcctID = #incomingAcctID)"
' Add the parameter so the SqlCommand can build the final query
myCmd.Parameters.Add(New SqlParameter("#incomingAcctID", (CInt(txtbx_accountNum.Text))))
' run the query and obtain a reader to get the results
Dim reader As SqlDataReader = myCmd.ExecuteReader()
' check if there are results
If (reader.Read()) Then
' populate the values of the controls
txtbx_accountName.Text = reader(0)
End If
' Close all connections
myCmd.Dispose()
myConn.Close() ' Close connection
myConn.Dispose()
i am not pro but i do like this,sorry if this not helped you:
if your Stored procedure is created to add and edit than write this and call it where you want to add:
private sub NAME(ByVAL Parameter1 name as integer,
ByVAL Parameter2 name as string,
ByVAL Parameter3 name as boolean)
Dim strConn As String = ConfigurationManager.ConnectionStrings("databaseXYZ").ConnectionString
Dim myConn As New SqlConnection(strConn)
Dim myCmd As SqlCommand
try
myConn.Open()
sqlCommand = New SqlCommand("PRCEDURE_NAME", myConn )
sqlCommand.CommandType = CommandType.StoredProcedure
dim param as new System.Data.SqlClient.SqlParameter
param.parameterName="#send_parameter1"
param.Direction = ParameterDirection.Input
param.Value = send_parameter1
dim param1 as new System.Data.SqlClient.SqlParameter
param1.parameterName="#send_parameter2"
param1.Direction = ParameterDirection.Input
param1.Value = send_parameter2
sqlCommand.Parameters.Add(Param)
sqlCommand.Parameters.Add(Param1)
sqlCommand.ExecuteNonQuery()
catch ex as exception
throw
End Try
myConn.Close()
myConn = Nothing
end sub
I'm a dummy!!!
Here is the solution, for all interested parties.
Click Event Handler (w/ nested Try-Catch):
txtbx_accountName.Text = DataSetTableAdapter.SearchNameQuery(CInt(txtbx_accountNum.Text)).ToString
SearchNameQuery:
SELECT AcctName FROM DataSetTable WHERE AcctID = #incomingAcctID
More notes on this:
- The dataset is already included in the project

Issue connecting to MySQL using a Class for Connectionstring and Command?

Apologies for the poor wording in the title, I'm new to OOP VB and I have no idea how to describe the problem I'm having!
I'm attempting to create a login form that's connecting to MySQL via a class that handles the logging in.
It connects no problem but I'm having issues with creating an SQL command to pull data from the database.
Here's the SQLConnection Class
Imports MySql.Data.MySqlClient
Imports System.Threading
Public Class SQLConnection
Private serverhost As String
Private db As String
Private userid As String
Private pwd As String
Private Shared cn As New MySqlConnection
Private Shared commandstring As New MySqlCommand
Public Property Server As String
Get
Return serverhost
End Get
Set(ByVal value As String)
serverhost = value
End Set
End Property
Public Property Database As String
Get
Return db
End Get
Set(ByVal value As String)
db = value
End Set
End Property
Public Property User As String
Get
Return userid
End Get
Set(ByVal value As String)
userid = value
End Set
End Property
Public Property Password As String
Get
Return pwd
End Get
Set(ByVal value As String)
pwd = value
End Set
End Property
Public Property command As MySqlCommand
Get
Return commandstring
End Get
Set(ByVal value As MySqlCommand)
commandstring = value
End Set
End Property
Private Shared ReadOnly Property Conn As MySqlConnection
Get
Return cn
End Get
End Property
Public Shared Function TryConn(ByVal obj As SQLConnection) As Boolean
Try
Dim connectionstring As String =
"server=" & obj.Server &
";database=" & obj.Database &
";user id=" & obj.User &
";password=" & obj.Password
cn = New MySqlConnection
cn.ConnectionString = connectionstring
If cn.State = ConnectionState.Closed Then
cn.Open()
End If
Return True
cn.ConnectionString = ""
Catch ex As Exception
Return False
End Try
End Function
End Class
Here's the login form Code snippet:
Try
Dim Conn As New SQLConnection
Dim reader As MySqlDataReader
With Conn
.Server = "localhost"
.Password = ""
.User = "root"
.Database = "customers"
End With
If SQLConnection.TryConn(Conn) = True Then
Dim Query As String
Query = String.Format("SELECT * FROM users WHERE Username = '{0}' AND Password = '{1}'", Me.UsernameTextBox.Text.Trim(), Me.PasswordTextBox.Text.Trim())
sql = New MySqlCommand(Query, Conn)
reader = sql.ExecuteReader
Dim count As Integer
count = 0
While reader.Read
count = count + 1
End While
If count = 1 Then
Me.Hide()
sqlloading.Show()
ElseIf count > 1 Then
errorform.FlatAlertBox1.Text = "Username and password are duplicate"
errorform.Show()
Else
errorform.FlatAlertBox1.Text = "Wrong username or password"
errorform.Show()
End If
Me.Hide()
Else
End If
Catch
End Try
When running this I get
"Value of type 'WindowsApplication1.SQLConnection' cannot be converted to 'MySql.Data.MySqlClient.MySqlConnection'.
The problem causing the error message appears to be on this line:
sql = New MySqlCommand(Query, Conn)
Because Conn is an instance of your SQLConnection type, but has to be a MySql.Data.MySqlClient.MySqlConnection instance, that you have created as a private property of SQLConnection.
You need to make a few changes:
Make Conn and TryConn methods normal, non shared methods
Make the cn field non shared.
Have the SQLConnection class implement IDisposable, making sure to dispose cn when it is disposed.
Change the login form code block to the below:
Try
Using Conn As New SQLConnection
With Conn
.Server = "localhost"
.Password = ""
.User = "root"
.Database = "customers"
End With
If SQLConnection.TryConn(Conn) = True Then
Const Query As String = "SELECT * FROM users WHERE Username = #username AND Password = #password"
' The line below fixes the error.
Using sql As MySqlCommand = New MySqlCommand(Query, Conn.Conn)
sql.Parameters.AddWithValue("#username", Me.UsernameTextBox.Text.Trim())
sql.Parameters.AddWithValue("#password", Me.PasswordTextBox.Text.Trim())
Using reader As MySqlDataReader = sql.ExecuteReader
Dim count As Integer
count = 0
While reader.Read
count = count + 1
End While
If count = 1 Then
Me.Hide()
sqlloading.Show()
ElseIf count > 1 Then
errorform.FlatAlertBox1.Text = "Username and password are duplicate"
errorform.Show()
Else
errorform.FlatAlertBox1.Text = "Wrong username or password"
errorform.Show()
End If
Me.Hide()
End Using
End Using
End If
End Using
Catch
' at least log the error?
End Try
This will solve you immediate problems, but there is room left for improvement. Instead of formatting your SQL yourself like this:
Query = String.Format(
"SELECT * FROM users WHERE Username = '{0}' AND Password = '{1}'",
Me.UsernameTextBox.Text.Trim(), Me.PasswordTextBox.Text.Trim())
You should really use SQL parameters to prevent SQL injection attacks, refer to the Little Bobby Tables story for reasons why. I have updated the code snippet above to improve this.
A final remark: you are now storing passwords as unencrypted plain text in your database. That is considered to be not secure. Passwords should always be stored and transmitted across the wire in an encrypted format.
Your Dim Conn As New SQLConnection is using the SQLConnection class.
If you're using MySQL, try have a look here.
I added the whole function from the login form to the SQLConnection class
Then Called it using:
Try
Dim Conn As New sqltryclass
With Conn
.Server = "localhost"
.Password = ""
.User = "root"
.Database = "adminapp"
End With
If sqltryclass.TryLogin(Conn) = True Then
Me.Hide()
sqlloading.Show()
Else
End If
Catch
End Try