how to inner join two tables or more tables from ms access database with vb.net? - vb.net

I have three tables in access database and a Application in vb.net where i am trying to search data from all three tables by TextBox but it is giving error.can someone tell me how to do this?
enter code here
Private Sub check()
Dim Myconn As New OleDbConnection(constr)
Dim adapter As New OleDbDataAdapter()
Dim command As New OleDbCommand()
Dim sql = "select descriptionofgoods,remarks,mode from tabel1 INNER JOIN table2 ON tabel1.id = tabel2.id inner join tabel3 on tabel1.id = tabel3.id;"
Try
Myconn.Open()
dt.Clear()
If TextBox2.Text > "" Then
sql = sql & " and [id] = ? "
command.Parameters.AddWithValue("id", TextBox1.Text)
End If
command.Connection = Myconn
command.CommandText = sql
adapter.SelectCommand = command
adapter.Fill(dt)
If dt.Rows.Count > 0 Then
DataGridView1.DataSource = dt
DataGridView1.Refresh()
Else
MessageBox.Show("ITEM NOT FOUND")
End If
Catch exp As Exception
Throw exp
Finally
If Myconn IsNot Nothing Then Myconn.Close()
End Try
End Sub

A lot of your code is redundant and can be removed:
Using da as New OleDbDataAdapter("select descriptionofgoods,remarks,mode from tabel1 INNER JOIN table2 ON tabel1.id = tabel2.id inner join tabel3 on tabel1.id = tabel3.id", constr)
Dim dt = DirectCast(DataGridView1.DataSource, DataTable)
dt.BeginLoadData()
dt.Clear()
If Not string.IsNullOrEmpty(TextBox2.Text) Then
da.SelectCommand.CommandText &= " and tabel1.[id] = ? "
da.SelectCommand.Parameters.AddWithValue("id", TextBox1.Text) 'why is this TextBox1 when you tested textbox2 in the If?
End If
adapter.Fill(dt)
dt.EndLoadData()
End Using
Notes:
Use Using; you then don't need your Try/Finally
DataAdapter knows how to create and open a connection itself
Don't catch exceptions only to throw them again; it disrupts the stack trace. Dont put a catch at all if youre not going to catch anything; Try ... Finally is legal, Throw on its own is legal (doesn't disrupt stack trace)
Do not terminate an SQL with a semicolon if you want to add to it. Don't terminate a single statement SQL with a semicolon anyway
You have several tables with an ID column; Access might let you get away with not specifying which ID you're talking about but proper databases won't so get in the habit now of fully qualifying every column (in your select too)
See the comment about TextBox1/TextBox2
Please.. name your controls properly. "name of a type of object plus a serial number" is not a good name for anything; your name is Pankaj Babbar, not human105874274365. You name your local variables well but not your class level ones, which is definitely the wrong way round
To rename a control after you add it to a windows form, click on it, then change then text in the (Name) line of the property grid
Telling a datatable youre about to/have finished loading data improves performance
Bound controls update automatically (if you ever use BindingSource investigate the RaiseListChangedEvents setting too)

Related

Visual Basic, Copying Success but does not Insert data into SQL TABLE

I have some problems here. I need help.
Recently, I have created a local database called stock.mdf and the application will be getting all the data from the hosting MySQL database into this local SQL Server database.
I am using sqlBulkCopy to inserting all the data. I have tried to view it after inserting. But when I close my application, I head back to check the table data. It does not inserted. Why is that?
Here is my code:
Here will be retrieving the data from the hosting
Dim connStr As String = "server=xxxx;user=xxx;database=xxx;password=xxxx;"
Dim conn As New MySqlConnection(connStr)
Dim cmd As New MySqlCommand
Dim Adapter As New MySqlDataAdapter
Dim StockData As New DataTable
Try
Dim SQL As String = "SELECT * FROM stock"
Console.WriteLine("Connecting to MYSQL.....")
conn.Open()
cmd.Connection = conn
cmd.CommandText = SQL
Adapter.SelectCommand = cmd
Adapter.Fill(StockData)
' StockViewGrid.DataSource = StockData
Catch ex As Exception
Console.WriteLine(ex.ToString())
Finally
conn.Close()
Console.Write("Done")
End Try
This will be the places where sqlBulkCopy working:
As well, I am trying to view from the stock table.
Dim Local_connectionStr As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|stock.mdf;Integrated Security=True"
Dim Local_conn As New SqlConnection(Local_connectionStr)
Dim Local_cmd As New SqlCommand
Dim Local_Adapter As New SqlDataAdapter
Dim Local_StockData As New DataTable
Try
Using sqlBulkCopy As New SqlBulkCopy(Local_conn)
'Set the database table name
sqlBulkCopy.DestinationTableName = "stock"
'[OPTIONAL]: Map the DataTable columns with that of the database table
sqlBulkCopy.ColumnMappings.Add("stockId", "stockId")
sqlBulkCopy.ColumnMappings.Add("id_android", "id_android")
sqlBulkCopy.ColumnMappings.Add("itemCode", "itemCode")
sqlBulkCopy.ColumnMappings.Add("quantity", "quantity")
Local_conn.Open()
sqlBulkCopy.WriteToServer(StockData)
Local_conn.Close()
End Using
Catch ex As Exception
Console.WriteLine(ex.ToString())
Finally
Local_conn.Close()
Console.Write("Done")
End Try
Try
Dim SQL As String = "SELECT * FROM stock"
Console.WriteLine("Connecting to MYSQL.....")
Local_conn.Open()
Local_cmd.Connection = Local_conn
Local_cmd.CommandText = SQL
Local_Adapter.SelectCommand = Local_cmd
Local_Adapter.Fill(Local_StockData)
StockViewGrid.DataSource = Local_StockData
Catch ex As Exception
Console.WriteLine(ex.ToString())
Finally
Local_conn.Close()
Console.Write("Done")
End Try
Since I can't comment (not enough points) I will put my thoughts here. Can you check that you got the expected data with a
Console.WriteLine(StockData.Rows.Count.ToString)
Console.ReadLine()
Also, your destination table doesn't have a PK that is auto increment, does it?
Sorry about the comment as an answer. (Untested code)
Unfortunately your code extracts are lacking headers etc, so are not complete, and I cannot be absolutely certain, BUT in your retrieving routine you seem to be declaring StockData as a local variable. This means that, although this may well be being filled with the data from MySQL, it is immediately discarded on exiting from this routine. Therefore the StockData variable in the sqlBulkCopy routine will be empty, and therefore will insert nothing. You need to fix your scope and make sure that the StockData read from MySQL is the same StockData used in SqlBulkCopy.

Visual Studio - multiple Table to multiple DataGridView with MS Access

how can i populate multiple table into multiple DataGridview?
for example i have 3 tables which is table1, table2 and table3, and in my form i have 3 dataGridView with name of dataGridView1, dataGridView2 and dataGridView3. i found this solution Updating an Access Database via a DataGridView Using OLEDB in VB.NET as a result of my code.
function loadDatabaseDataToGridView
Dim msAccessFilePath As String
Dim con As New OleDbConnection
Dim dataTable, dataTable2, dataTable3, dataTable4 As New DataTable
Dim olebDataAdapter As New OleDbDataAdapter
Dim da As New OleDbDataAdapter
Dim dataSet As New DataSet
Private Sub loadDatabaseDataToGridView()
Try
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & msAccessFilePath
dataSet.Tables.Add(dataTable)
olebDataAdapter = New OleDbDataAdapter("Select * from table1", con)
olebDataAdapter.Fill(dataTable)
olebDataAdapter = New OleDbDataAdapter("Select * from table2", con)
olebDataAdapter.Fill(dataTable2)
olebDataAdapter = New OleDbDataAdapter("Select * from table3", con)
olebDataAdapter.Fill(dataTable3)
DataGridView1.DataSource = dataTable.DefaultView
DataGridView2.DataSource = dataTable2.DefaultView
DataGridView3.DataSource = dataTable3.DefaultView
Dim cb = New OleDbCommandBuilder(olebDataAdapter)
cb.QuotePrefix = "["
cb.QuoteSuffix = "]"
MessageBox.Show("Successfull")
Catch ex As Exception
MessageBox.Show("Failed")
con.Close()
End Try
con.Close()
End Sub
function SaveChanges
'Perform this on Button Save is Click
Private Sub saveChanges()
olebDataAdapter.Update(dataSet)
End Sub
This code is working as excpected, it is populating the data from MS Access file but when i clicked the button save to save the changes on edited data, an error has occurred.
THE ERROR:
Concurrency violation: the UpdateCommand affected 0 of the expected 1 records
anyone does know how to properly implement of what i am trying to achieve? Thank You Very Much!!!
Each DataAdapter object only has a single UpdateCommand, so you'll need one for each data table. If it runs the update command and no rows are updated (because the update command is actually for a table that you haven't changed) then you'll get the Concurrency Violatation.
It actually gets more complicated than this if your tables are related as the order that inserts, updates and deletions occur can be critical.
If you create a Strongly Typed Dataset it generates designer code that includes a TableAdapterManager class and all of the required data adapters. It might be worth playing around with this just so that you can see how the generated code works.
Just a note, the 'Concurrency violation' exception is actually there so that you can design an update command that will only succeed if the contents of the record in the database match the data held locally (to prevent you from overwriting another user's changes). Search for Optimistic Locking for more details.

How can I use multiple connection in If else code blocks?

I want to use multiple connection in if else code block but it's giving the following error when I checked in a Messagebox :
"Argument prompt cannot be converted to string"
Here is my code :
Try
Conn.Open()
Com.CommandText = "Select * FROM Table1 WHERE ID=" & txtID.Text & " AND DOR=#01/01/1900# AND Paid = '0' ORDER BY DOI"
Dr = Com.ExecuteReader
If Dr.Read = True Then
txtInstNo.Text = Dr(2)
txtInstAmount.Text = Dr(4)
Else
If MsgBox("Wait! You're not allowed to do it. Do you still want to continue ? ", MsgBoxStyle.YesNo Or MsgBoxStyle.Question, "Alert") = MsgBoxResult.Yes Then
Try
Dim Con As New OleDbConnection
Dim Comm As New OleDbCommand
Dim Dr2 As OleDbDataReader
Con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database.accdb"
Con.Open()
Comm.Connection = Con
Comm.CommandText = "Select * FROM Table1 WHERE ID=" & txtID.Text & " AND DOR=#01/01/1900# AND Paid = '0' ORDER BY DOI"
Comm.CommandType = CommandType.Text
Dr2 = Comm.ExecuteReader
MsgBox(Dr2) <-- Here I got that error
If Dr.Read = True Then
txtInstNo.Text = Dr(2)
txtInstAmount.Text = Dr(4)
Else
MsgBox("Sorry, no record found",MsgBoxStyle.Exclamation, "Alert")
End If
Dr2.Close()
Con.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End If
Dr.Close()
Conn.Close()
Catch ex As Exception
MsgBox(ex.Message)
End Try
Your query might be returning entire rows, objects, widgets or whatever. As #Andrew Morton pointed out, it's a Data Reader. It's not going to implicitly convert your result. You'll have to manipulate your reader result and convert it to a string to do anything useful. You'll also have to handle if your DataReader returns a null result, which when converted should be "" an empty string.
If you just want to see what Dr2 contains, you could try MsgBox(CStr(Dr2)). No error handling, if it throws an exception.
There are a few things which could be modified in your code to make it a bit shorter and so easier to track down what is not working. It is easier to isolate a problem if you have the minimal amount of code which shows the problem: How to create a Minimal, Complete, and Verifiable example.
I'll show my suggestion for a minimal amount of code on a new form which should help you narrow down where the problem is, and then I'll go over why I have written it that way and what could be going wrong.
Option Strict On
Option Infer On
Imports System.Data.OleDb
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Database.accdb"
Dim sql = "SELECT InstNo, InstAmount FROM Table1 WHERE ID = ? AND DOR = #01/01/1900# AND PAID='0' ORDER BY DOI"
' lists to hold the retrieved data
Dim instNos As New List(Of String)
Dim instAmounts As New List(Of String)
' get the data
Using conn As New OleDbConnection(connStr)
Using cmd As New OleDbCommand(sql, conn)
cmd.Parameters.Add(New OleDbParameter With {.ParameterName = "#ID",
.DbType = DbType.String,
.Value = txtID.Text})
conn.Open()
Dim rdr = cmd.ExecuteReader()
While rdr.Read
instNos.Add(rdr.GetString(0))
instAmounts.Add(rdr.GetString(1))
End While
End Using
End Using
' act on the data
If instNos.Count = 0 Then
MsgBox(String.Format("No records were found for ID ""{0}"".", txtID.Text))
Else
txtInstNo.Text = String.Join(vbCrLf, instNos)
txtInstAmount.Text = String.Join(vbCrLf, instAmounts)
End If
End Sub
End Class
The code.
I start with Option Strict On to make sure that all data types match up and I haven't done anything else silly which Visual Studio can point out to me.
I use Option Infer On so that I don't have to type out the type of variables when the compiler can infer what they are.
I used just one Button on the form along with the three named textboxes as we are going for minimal code.
I set up the two strings which are going to be used in one place at the top of the sub because it is easier to maintain the code that way. Normally, you would declare variables just before they are used to minimise their scope.
I specified exactly which columns I want from the database. There is no point retrieving all of them with *. I had to guess what the columns are called - you will need to put in the actual names if they are different.
The result of a query to the database might have more than one record, so I initialise Lists for the data. (Your query has an ORDER BY so I assume that there could be more than one record.)
The Using statement makes sure that resources are released cleanly whatever else happens.
For OleDb, parameters are normally represented by a ?. (If there is more than one, they are all represented by question marks and the parameters must be added in the order in which they are to be put into the query.) I had to guess at the data type for the ID column - please put in the correct type. When you create the parameter, you can still use a meaningful name for it, even though it is ignored by the computer.
Next, the data (if any) is read. I do nothing else at this point except read the data to keep it fast and tidy. I assumed that the data to be retrieved is strings, hence the GetStrings. You should adjust that if required, and also the types of the Lists to match.
Now that the data has been read, I act on it. If there was no data, show an appropriate message, and if there was data then I put it into multiline textboxes to show it. Note that I wrote multiline: if it was a single line textbox then only the last line would be visible. Other ways of displaying it could be more useful, for example a DataGridView - in which case I might have read the data into a DataTable or a list of some class.
What could go wrong.
In your query, you have AND DOR = #01/01/1900# - is this correct?
In your query, you have AND PAID = '0' - is PAID actually a string? If it is a number then it should be AND PAID = 0. (The DB should convert the string "0" to the number zero, but why make it do extra work?)
Now that you have multiline textboxes for the results, you can see if it just happens that the last records found happened to be blank, and are simply not visible in a single-line textbox.
Finally, are you sure it is using the correct database file?

I want to display records in my textbox

When i input the id number of the student in my TextBox, i want the details of that particular students to be displayed in my textbox, without using datagrid. i am using vb.net.
That is my code and i don't understand what's wrong:
cmd.CommandText = "SELECT * from tblsupplier where pro_code = '" & txcode.Text & "'"
dr = cmd.ExecuteReader
txname.Text = dr.item("sup_product")
txprice.Text = dr.Item("sup_price")
First off, you have left your application open to sql injection by adding the value of the textbox inline. Look up this topic please:
http://en.wikipedia.org/wiki/SQL_injection
As for your code, you need to call dr.Read() before you can actually access any properties from your query.
while (dr.Read()) {
// Do stuff
}
Good luck!
It would help if you could provide additional details about the error, friend. Like what SQL you are using, what was the error message, and which event triggers this reader command.
As it stands, it seems you haven't really sent the DataReader to scan the database. You need the While reader.read() loop.
Here is an example, using OLEDB in a function that fetches the data
Note that connstring is my SQL connection string to an Access Database
Dim conn As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data source=MyDatabase.mdb;Jet OLEDB:Database Password=;")
Function Mycheckifexistss(ByVal sqlCMDstring As String)
Dim sqlCmd As New OLEDBCommand(sqlCMDstring, conn)
Dim reader As OLEDBDataReader
Dim result As String = ""
Try
conn.Open()
reader = sqlcmd.ExecuteReader
While reader.Read
result = reader(0) 'this returns the first field of the queried result.
End While
conn.Close()
Return result
Catch ex As Exception
conn.Close() 'the first thing you want to do in an error, is to close the connection first.
MsgBox(ex.ToString)
End Try
End Function

How do I assign the results of an SQL query to multiple variables in VB.NET?

This is my first attempt at writing a program that accesses a database from scratch, rather than simply modifying my company's existing programs. It's also my first time using VB.Net 2010, as our other programs are written in VB6 and VB.NET 2003. We're using SQL Server 2000 but should be upgrading to 2008 soon, if that's relevant.
I can successfully connect to the database and pull data via query and assign, for instance, the results to a combobox, such as here:
Private Sub PopulateCustomers()
Dim conn As New SqlConnection()
Dim SQLQuery As New SqlCommand
Dim daCustomers As New SqlDataAdapter
Dim dsCustomers As New DataSet
conn = GetConnect()
Try
SQLQuery = conn.CreateCommand
SQLQuery.CommandText = "SELECT Customer_Name, Customer_ID FROM Customer_Information ORDER BY Customer_Name"
daCustomers.SelectCommand = SQLQuery
daCustomers.Fill(dsCustomers, "Customer_Information")
With cboCustomer
.DataSource = dsCustomers.Tables("Customer_Information")
.DisplayMember = "Customer_Name"
.ValueMember = "Customer_ID"
.SelectedIndex = -1
End With
Catch ex As Exception
MsgBox("Error: " & ex.Source & ": " & ex.Message, MsgBoxStyle.OkOnly, "Connection Error !!")
End Try
conn.Close()
End Sub
I also have no problem executing a query that pulls a single field and assigns it to a variable using ExecuteScalar. What I haven't managed to figure out how to do (and can't seem to hit upon the right combination of search terms to find it elsewhere) is how to execute a query that will return a single row and then set various fields within that row to individual variables.
In case it's relevant, here is the GetConnect function referenced in the above code:
Public Function GetConnect()
conn = New SqlConnection("Data Source=<SERVERNAME>;Initial Catalog=<DBNAME>;User Id=" & Username & ";Password=" & Password & ";")
Return conn
End Function
How do I execute a query so as to assign each field of the returned row to individual variables?
You probably want to take a look at the SqlDataReader:
Using con As SqlConnection = GetConnect()
con.Open()
Using cmd As New SqlCommand("Stored Procedure Name", con)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("#param", SqlDbType.Int)
cmd.Parameters("#param").Value = id
' Use result to build up collection
Using dr As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection Or CommandBehavior.SingleResult Or CommandBehavior.SingleRow)
If (dr.Read()) Then
' dr then has indexed columns for each column returned for the row
End If
End Using
End Using
End Using
Like #Roland Shaw, I'd go down the datareader route but an other way.
would be to loop through
dsCustomers.Tables("Customer_Information").Rows
Don't forget to check to see if there are any rows in there.
Google VB.Net and DataRow for more info.