selecting from one database and inserting row to new database - vb.net

I'm looking for a pseudo code to write a VB.NET cursor to select columns from one table in one database and inserting it into another table in a different database (they are *not on the same server) using data adapter etc.
I just need something to refer to as I learn. Thanks
Dim selectStr As String = _
"select * from db1"
Dim insertStr As String = _
"insert into db2(col1)"
Try
da_adapter = New OleDb.OleDbDataAdapter(selectStr, connStr)
da2_adapter = New OleDb.OleDbDataAdapter(insertStr, connStr2)
da_adapter.SelectCommand.CommandTimeout = 720
da_adapter.Fill(ds)
da2_adapter.SelectCommand.CommandTimeout = 720
da2_adapter.Fill(ds)
Catch ex As Exception
End Try

In your original code, this part is wrong:
da2_adapter = New OleDb.OleDbDataAdapter(insertStr, connStr2)
When you create a data adapter that way, the SQL statement you provide becomes part of the SelectCommand. You want yours to be part of the InsertCommand, which you need to do yourself:
Dim cmd2 As New OleDb.OleDbCommand(insertStr, connStr2)
da2_adapter = New OleDb.OleDbDataAdapter
da2_adapter.InsertCommand = cmd2
Also, you need to set the AcceptChangesDuringFill property of the first data adapter to False. That way, instead of setting the RowState of all the rows to Unchanged after populating the DataTable, they will remain as Added and ready to be inserted.
You then need to call Update on the second data adapter to save the data rather than calling Fill, which retrieves data.

Related

Filtering by ID column

I am trying to filter a table from Ms access DB in visual studio by ID (PID) column but I can't figure out how to convert int to string, or to make it work.
Any ideas please.
con.ConnectionString = dbProvider & dbSource
con.Open()
If PIDfindTextBox.Text = "" Then
MessageBox.Show("Please enter a Patient ID number")
Else
PatienrocordBindingSource.Filter = "((PID,'system.string') like '" & PIDfindTextBox.Text & "')"
If PatienrocordBindingSource.Count <> 0 Then
With dataGridView1.DataSource = PatienrocordBindingSource
End With
Else
MessageBox.Show("Searched Patient ID was not found")
PatienrocordBindingSource.Filter = Nothing
End If
End If
End Sub
Your code is very confused. It opens a database connection then sets a bindingsource filter, this isn't really how things go
A bindingsource is a device that sits between a model of data such as a datatable (which is not a table in a database) and a UI element such as a datagridview or other controls. The bindingsource can filter the data it finds in the model. None of this is anything to do with filling the model up with data in the first place, which often is done by pulling it out of a database
You can probably avoid interacting with a database connection entirely; if you use an OledbDataAdapter you can pull data out of your database and load it into a datatable in your program's memory
You thus have a choice of where to filter your data. You either load the entire database into your program's memory and then use bindingsource filter to show just the one if you want - all the data lives in the datatable and only some of it passes through the bindingsource ..
Or you only download some of the data out of the database and into the datatable, and then you don't need to filter it in the bindingsource
You can also take a hybrid approach of loading, say, 10 records into the datatable and then filtering In the bindingsource
Choose your scenario - most people opt for the middle one where you just download the data you need. There are plenty of examples out there but as a rough template, searching a database table by I'd and pulling the results would look like:
Dim da as New OleDbDataAdapter("SELECT * FROM Person WHERE Id =?", "connection string here")
da.SelectCommand.Parameters.AddWithValue("id", Convert.ToInt32(idTextbox.Text))
Dim dt as New DataTable
da.Fill(dt)
bindingsource.DataSource = dt
If you had 10 rows in your datatable and wanted to filter to just some one id
bindingsource.Filter = "[Id] = " & idFilterTextBox.Text
You don't need to use both of these approaches; use the one that is right for your context

How can i set the value from the last row in an specific column in a variable in VB.Net

I'm develop an application using forms in vb.net with visual studio 2019
I have code in the event click for one button
Dim oda As New OleDbDataAdapter
Dim ods As New DataSet
Dim consulta As String
Dim cadena As New OleDbConnection
Dim comando As New OleDbCommand
Try
cadena.Open()
comando = New OleDbCommand("Insert into QRQC (Nombre,NumControl,Fecha,Hora,Turno)" &
"values(txt_nombre,txt_numControl,lbl_fecha,lbl_hora,cBox_turno)", cadena)
consulta = "Select *From QRQC"
oda = New OleDbDataAdapter(consulta, cadena)
ods.Tables.Add("QRQC")
oda.Fill(ods.Tables("QRQC"))
Dim row As Integer
row = ods.Tables("QRQC").Rows.Count - 1
courrentId = ods.Tables("QRQC")(row)("ID_QRQC").ToString()
frm_newPt2.lbl_folioQRQC.Text = courrentId
cadena.Close()
Catch ex As Exception
MsgBox("Error al generar el registro en la base de datos", vbCritical, "Aviso")
Console.WriteLine(ex)
cadena.Close()
GoTo skip
End Try
Everything goes perfectly, but when I delete some record on my DB this part of the code always return the value 102
courrentId = ods.Tables("QRQC")(row)("ID_QRQC").ToString()
How can i solve this problem?
First of all, your insert command is wrong, and will not work.
You have "values(txt_nombre. etc etc."
But that is just a string and NOT the actual values from the form. So you are actually going to "instert txt_nombre" into that table and NOT the value of that label or text box on the form!!!
So you need to fix and get your insert command working FIRST.
And if this is just editing data then consider using the data binder, since navigation, editing, deleting and saving of data to/from the table can occur 100% automatic whiteout ANY code on your part.
so first up is to fix that insert command. You can't JUST use a string with the names of the controls else that would actually as noted try to insert the names of the controls as text and NOT the values of the controls.
And lets clean up a few other things. No need for a dataset, since a dataset is a SET of tables - we only dealing with one table (so use a data table).
But as noted, before we mess with data tables, we have to fix that insert command.
It will, can look like this:
Dim strSQL As String
strSQL = "Insert into QRQC (Nombre,NumControl,Fecha,Hora,Turno) " &
"VALUES(#nombre,#numControl,#fecha,#hora,#turno)"
Using cmdSQL As New OleDbCommand(strSQL,
New OleDbConnection(My.Settings.TestDB))
cmdSQL.Parameters.Add("#nombre", OleDbType.Integer).Value = txt_nombre.Text
cmdSQL.Parameters.Add("#numControl", OleDbType.Integer).Value = txt_numControl.Text
cmdSQL.Parameters.Add("#fecha", OleDbType.Integer).Value = lbl_fecha.Text
cmdSQL.Parameters.Add("#hora", OleDbType.Integer).Value = lbl_hora.Text
cmdSQL.Parameters.Add("#turno", OleDbType.Integer).Value = txt_nombre.Text
cmdSQL.Connection.Open()
cmdSQL.ExecuteNonQuery()
End Using
So you have to "replace" the string values in the sql with the ACTUAL values you are using.
You also don't show where/how you setup your connection to the database. I guessed that you used the applications settings and the connection builder - so you have to change TestDB to your actual connection that you used.
The above will thus get your insert command working.
At that point, you can post a new question in that after you do a insert, how to get the new autonumber primary key, or whatever else you wanted to do, but your insert statement as written will not work.
As noted, perhaps it better to use data bound controls. This will result in a Access like design experience, and you not having to write ANY code to edit a table in vb.net.
And it not clear if the control names I used are correct (or they are even controls on the form), but if they are, then ".Text" is required to grab the values. You have to of course change (check) that the control names I used and guessed are correct.
You also have to change the data type "integer" I used in above to the correct data types. For text I recommend you use .VarWChar

My code seems to merge datasets but it does not update to the access DB

I am trying to merge two tables and update one table with the merged records from two separate MS access databases
Both tables are identical and both tables are password protected with auto number primary key
The following code merges the datasets memory, or at least by the msgbox messages the record count is correct.
But it does not update to the table in the access database..
I have searched the net long and hard and am really at a loose end..
daDBTarget = New OleDbDataAdapter
daDBTarget.SelectCommand = New OleDbCommand("SELECT * FROM DBUSERTASK", Conn1)
daDBTarget.Fill(dsDBTarget, "tbl1")
daDBSource = New OleDbDataAdapter
daDBSource.SelectCommand = New OleDbCommand("SELECT * FROM DBUSERTASK", conn2)
daDBSource.Fill(dsDBSource, "tbl2")
MsgBox("Dataset 1 dstTaskComp is full with " & dsDBTarget.Tables(0).Rows.Count & vbCr & vbCr & "Dataset 2 dstTaskComp is full with " & dsDBSource.Tables(0).Rows.Count)
dsDBTarget.Tables("tbl1").Merge(dsDBSource.Tables("tbl2"), True)
MsgBox("Dataset 1 dstTaskComp is now merged and full with " & dsDBTarget.Tables(0).Rows.Count)
dsDBTarget.AcceptChanges()
Dim cb As New OleDbCommandBuilder(daDBTarget)
daDBTarget.Fill(dsDBTarget)
cb.GetUpdateCommand()
daDBTarget.Update(dsDBTarget)
There are a couple of details I dont know. For instance, if the source/master has deleted rows which are not (yet) deleted in the destination, should they be deleted as part of the merge? Since they do not exist in the Source, nothing will happen to them in the process unless you handle it manually. I ignored that aspect since it was not mentioned.
The key element to know is that each row has a RowState indicating what -- if anything -- the DataAdapter will do with each row. There are some key steps elements wrong or missing:
When a DataAdapter fills a table, it sets all the row states to Unchanged. In order for the source rows to be eligible for insert/update to the Dest, you want them to have a RowState of Added. AcceptChanges clears all the state flags.
In order to prevent simply adding copies (with new Ids), you need to also load the schema, so it can compare the PK and know how to handle new rows.
When you merged, you use PreserveChanges = True which tells OleDB to ignore column level changes to the source.
Not related, but important is to dispose of DB Provider objects when you are done with them. This will merge 2 tables from the same DB, so the same connection can be used, but otherwise illustrates the process. I also skipped the DataSets as they are not essential.
Dim SQLa = "SELECT * FROM MergeA"
Dim SQLb = "SELECT * FROM MergeB"
Dim dtSrc As New DataTable
Dim dtDest As New DataTable
Using dbcon As New OleDbConnection(ACEConnStr)
Using da As New OleDbDataAdapter(SQLa, dbcon)
dbcon.Open()
' Do Not set the RowState to UnChanged, please
da.AcceptChangesDuringFill = False
da.Fill(dtSrc)
End Using
Using da As New OleDbDataAdapter(SQLb, dbcon)
Dim cb = New OleDbCommandBuilder(da)
' same connection, already open
' load the schema to get the PK etc
da.FillSchema(dtDest, SchemaType.Source)
da.Fill(dtDest)
' merge the tables
dtDest.Merge(dtSrc, False, MissingSchemaAction.Add)
Dim rows = da.Update(dtDest)
End Using ' close and dispose
End Using
The results:
XRay was in the source, but not the dest, so it was added.
All the RED items were that way in the Source only, so the column data was updated in the destination as is usually desired.
There are 3 new rows in the Source which were added (not shown)
Perhaps more important is that item 2 - Uniform exists in the Destination but had been deleted in the Source. The DataAdapter wont remove it because it is there and the code didnt change the RowState to Deleted. Merging will accumulate rows and column data changes depending on the options used, but removing deleted rows is more like a synch operation. It is pretty simple to incorporate though.

Cant save or update my SQL Server tables using vb.net

I am a complete beginner to .net and am confused at some basic things. Please help.
First of all the table I create and populate (by right clicking tables in server explorer) disappear once I restart the computer. how do I keep them.
Is there any better place/interface to type SQL queries in vb.net than the command prompt.
In the following code:
Dim cn As SqlConnection = New SqlConnection(strConnection)
cn.Open( )
' Create a data adapter object and set its SELECT command.
Dim strSelect As String = _
"SELECT * FROM Categories"
Dim da As SqlDataAdapter = New SqlDataAdapter(strSelect, cn)
' Load a data set.
Dim ds As DataSet = New DataSet( )
da.Fill(ds, "Categories")
This far the code runs fine but just to gain better understanding, I would like to ask that
while data from SQL Server database was saved into da in accordance to the query, why do we need to save/transfer it in the dataset object ds.
Is there any additional benefit of SqlCommand over SqlDataAdapter besides speed?
Dim autogen As New SqlCommandBuilder(da)
Dim dt As DataTable = ds.Tables("Categories")
' Modify one of the records.
Dim row As DataRow = dt.Select("CategoryName = 'Dairy Products'")(0)
row("Description") = "Milk and stuff"
gives an error when I use it with
da.Update(ds, "Categories")
regarding dt.select not returning any value.
What is the way out?
to answer your questions :
The tables you create with the server explorer are IN MEMORY. Same goes for dataset, they are in-memory representation of your table. As for your 2nd example, the DS you use isnt filled when you try to get the DT. hence why the DT is empty.
If your starting, I would suggest you go look into Linq-to-Sql (http://msdn.microsoft.com/en-us/library/bb425822.aspx) for a more up-to-date way of doing sql in .net ( I think its 4.0 framework)
As for the 2nd point, I'd say normally you should use store procedure for most of your sql commands .. the sqlcommand is use like this
Try
Cmd = New SqlClient.SqlCommand("st_InventoryStatus_Or_AnyStoreProcName_Or_ASqlQuery")
Cmd.CommandTimeout = 300 'not really needed'
Cmd.CommandType = CommandType.StoredProcedure 'you can type CommandType.Text here to use directly your "Select * from Category"'
Cmd.Parameters.Clear() 'just to be sure its empty, its not mandatory'
Cmd.Parameters.Add("#idCategory", SqlDbType.Int).Value = myCategory.Id 'here are the parameters of your store proc, or of your query ("select * from Category where Category.id = #Id")'
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Information)
End Try

Do columns need to match exactly when using dataadapter.update

I'm working on a project to import data from a Microsoft Access database into a blank MS-SQL database. The structure of the table in Access (VM) does not match up exactly with the table in MS-SQL (vlVerticalMarketing).
AccessTable VM SQLTable vlVerticalMarketing
ID (autonumber) VMID (PK, identity)
VM VerticalMarketing
Deleted (required)
Archive (required)
Other non-required fields
I'm filling the Access data into a DataTable DT using the following query:
select VM as VerticalMarketing, 0 as Deleted, 0 as Archive from VM where VM is not null
Then I change the name of the DataTable using:
DT.TableName = "vlVerticalMarketing"
From there, I pass the DataTable into a class function.
Public Function CopyFromDataTable(ByVal sourceDT As DataTable, ByVal TableName As String) As Boolean
Try
OpenDB()
Dim DA As New SqlDataAdapter("select VerticalMarketing, Deleted, Archive from " & TableName, Me.DBConn)
Dim CB = New SqlCommandBuilder(DA)
CB.QuotePrefix = "["
CB.QuoteSuffix = "]"
DA.InsertCommand = CB.GetInsertCommand(True)
Dim destDT = sourceDT.Copy()
DA.Update(destDT)
OpenDB is a class method that I use for other things and I know is good. It sets the connection string and creates DBConn as a SqlConnection object. The rest is standard VB.Net. Everything runs without error. Both sourceDT and destDT have data in them (viewed through the DataSet Visualizer while debugging). The problem is that no data gets passed out to the SQL database.
Any ideas on what I'm doing wrong that is causing the SQL database not to receive the data.
i think the problem is that the rows in destDt don't have RowState.Added when you call Update on the DataAdapter ... you can check the return value of the Update statement ... i guess it will be 0 because no inserts were executed ... you could check this with sql server profiler ...
as a workaround for this you could call DataRow.SetAdded() on the rows in your destDT ...