Multiple databases information display - mysql

I have a very difficult task, that I think exceeds my level of knowledge of databases. I am only learning it for a week, so I require help.
I currently have an old database that has tables for requests and customers. This information is currently displayed in ASP.NET
What I was required to do, was to connect a new database for users into this system, while keeping the tables for the requests in the old database. Thus it is using 2 databases. I have set it up so, when a user creates a new request, in the request tables it saves it with his userID from the new database, but when the table is being displayed, it uses this new userID to find the user information from the old customers table. Thus I ended up with this:
Sub BindDataGrid()
cmdoledb = New SqlCommand("SELECT r.customerid, r.RequestID, R.RequestDate, R.RequestDescription, a.AssignedTo, r.Urgency, r.ExCompletionDate from tbl_requests r, tbl_assignedto a where r.statusid = 1 and r.assignedtoid= a.assignedtoid ", objConn)
objConn.Open()
Dim rdr As SqlDataReader
Dim myItem As ListItem = New ListItem()
rdr = cmdoledb.ExecuteReader(0)
While rdr.Read()
myItem = New ListItem()
myItem.Value = rdr.GetInt32(0)
cmddb = New SqlCommand("SELECT SESFirstName + ' ' + SESLastName As fullname from SESLogin where SESLoginID = #customerID", objConnect)
cmddb.Parameters.AddWithValue("#customerID", myItem.Value)
objConnect.Open()
Dim anotherAdapter As New SqlDataAdapter(cmddb)
Dim dss As New DataSet
anotherAdapter.Fill(dss)
dgrdUsers.DataSource = dss
objConnect.Close()
End While
Dim myAdapter As New SqlDataAdapter(cmdoledb)
Dim ds As New DataSet
myAdapter.Fill(ds)
dgrdUsers.DataSource = ds
dgrdUsers.DataBind()
objConn.Close()
End Sub
Currently it displays nothing, and gives out an error for myItem.Value = rdr.GetInt32(0) being a Null. I went through it step by step and it loads customerids normaly into the myItem.Value, but when they run out, it is supposed to exit, but keeps going, thus giving an error.
This code is very silly i know, but with my knowledge, this is what I was able to come up with. Thus I require your help and advice, to fix this issue I am having.

Well, the first thing I would do is combine your two databases into one (preferably using views as replacements for you existing tables), if indeed you are using two dbs (it's not clear from your code sample whether you really are using two dbs or simply additional tables).
You are executing you primary query twice, once for a data reader and once for a dataadapter.fill. You should do the fill first and then iterate over the resulting rows. The code sample is using a list item in oreder to contain a single integer, unless you are not showing all of your code, you should just use an integer variable.
I don't know if it fits in with what you are doing or not, but you only need one dataset with two tables to contain the data you are retrieving.

Related

How to update data grid bound to data table with MySQL data adapter

I pull from my MySQL database, and fill it using a MySQLDataAdapter. MasterDataTable is my class level DT.
Dim SQLstring As String = "SELECT * FROM Inventory.Metadata"
Using cmdSel As New MySqlCommand(SQLstring, MySQLconn.conn)
Dim da As New MySqlDataAdapter(cmdSel)
da.Fill(MasterDataTable)
End Using
Somebody updates the MySQL database, and I want to refresh the data again.
MasterDataTable.Clear()
Dim SQLstring As String = "SELECT * FROM Inventory.Metadata"
Using cmdSel As New MySqlCommand(SQLstring, MySQLconn.conn)
Dim da As New MySqlDataAdapter(cmdSel)
da.Fill(MasterDataTable)
End Using
The problem is, if the user has something selected, it will clear their selection.
Obviously this clears the datatable and re-fills it. Is there any way to accomplish the same task without MasterDataTable.clear?
Used jmcilhinney's suggestion, created a separate table, compared the two, and deleted from main table if it didn't exist in the other.
Thanks :)

Updating an Access Table with a CSV File Automatically

Problem Background:
I have a Powershell script that I can execute from my Microsoft Access Form that scans through file folders that contain information on different facilities, and produces a CSV that looks something like:
SiteCode FacilityNumber DocumentType HyperlinkPath
DKFZ 10 DD1400 C:\FACILITIES DATABASE\path
DKFZ 10 FLRPLN C:\FACILITIES DATABASE\path
SMQL 17 P1 C:\FACILITIES DATABASE\path
SMQL 17 P2 C:\FACILITIES DATABASE\path
So that way every time new files are added to those folders, I can just run this script and produce an updated list of everything I have:
C:\...\Output\scanResults.csv
All I need now is to take that CSV file and update (or even overwrite) a Table that I have in an Access database, which has relationships to other tables and is used by various Queries and Forms in the database. The CSV columns are already named and formatted in the same way as the Access Table.
I've looked at and tried to replicate the following threads:
VBA procedure to import csv file into access
Access Data Project Importing CSV File In VBA
VBA Import CSV file
The closest answer I found is:
Sub Import()
Dim conn as new ADODB.Connection
Dim rs as new ADODB.Recordset
Dim f as ADODB.field
conn.Open "DRIVER={Microsoft Text Driver (*.txt; *.csv)};DBQ=c:\temp;"
rs.Open "SELECT * FROM [test.txt]", conn, adOpenStatic, adLockReadOnly, adCmdText
While Not rs.EOF
For Each f In rs.Fields
Debug.Print f.name & "=" & f.Value
Next
Wend
End Sub
But this obviously won't write the data into the table, and I could not understand what the author was trying to say with respect to changing Select to Insert.
I've also found:
DoCmd.TransferText acImportDelim, "YourCustomSpecificationName", _
"tblImport", "C:\SomeFolder\DataFile.csv", False
Since both of these are from 2010, I wonder if there isn't a better way to accomplish this in Access 2013. And while I can do this all manually, I would like to incorporate it into the VBA code I use to tell Powershell to produce the CSV, that way I can make it and then upload it immediately.
Any help or suggestions are greatly appreciated. I'm still very green to Access, VBA, and SQL statements in general, so this has been very much a "learning as I go" process.
I prefer to use SQL clauses and queries to import such data. The details depend on your exact configuration, but it tends to look something like this:
SELECT *
INTO MyTable
FROM [Text;FMT=CSVDelimited;HDR=No;DATABASE=C:\...\Output].[scanResults#csv]
Or append the information to the table instead:
INSERT INTO MyTable
(SiteCode, FacilityNumber, DocumentType, HyperlinkPath)
SELECT *
FROM [Text;FMT=CSVDelimited;HDR=No;DATABASE=C:\...\Output].[scanResults#csv]
This allows you to do checks before importing (using a WHERE clause), import only specific values, and allows you to customize a lot without using external files.
DATABASE= is followed by your folder name (use {} if there are characters that need escaping in there), and then followed by your file name with . replaced with #.
You can execute it by either saving it as a query, or using it as a string in either VBA or a macro. Note that I rarely recommend macro's, but you can execute them using a scheduled task and close Access after importing.
To backup and restore a relation before and after updating, you can use the following functions:
Public Function DeleteRelationsGiveBackup(strTablename As String) As Collection
Dim ReturnCollection As Collection
Set ReturnCollection = New Collection
Dim i As Integer
Dim o As Integer
Do While i <= (CurrentDb.Relations.Count - 1)
Select Case strTablename
Case Is = CurrentDb.Relations(i).Table
ReturnCollection.Add DuplicateRelation(CurrentDb.Relations(i))
o = o + 1
CurrentDb.Relations.Delete CurrentDb.Relations(i).NAME
Case Is = CurrentDb.Relations(i).ForeignTable
ReturnCollection.Add DuplicateRelation(CurrentDb.Relations(i))
o = o + 1
CurrentDb.Relations.Delete CurrentDb.Relations(i).NAME
Case Else
i = i + 1
End Select
Loop
Set DeleteRelationsGiveBackup = ReturnCollection
End Function
Public Sub RestoreRelationBackup(collRelationBackup As Collection)
Dim relBackup As Variant
If collRelationBackup.Count = 0 Then Exit Sub
For Each relBackup In collRelationBackup
CurrentDb.Relations.Append relBackup
Next relBackup
End Sub
Public Function DuplicateRelation(SourceRelation As Relation) As Relation
Set DuplicateRelation = CurrentDb.CreateRelation(SourceRelation.NAME, SourceRelation.Table, SourceRelation.ForeignTable)
DuplicateRelation.Attributes = SourceRelation.Attributes
Dim i As Integer
Dim fldLoop As Field
Do While i < SourceRelation.Fields.Count
Set fldLoop = DuplicateRelation.CreateField(SourceRelation.Fields(i).NAME)
fldLoop.ForeignName = SourceRelation.Fields(i).ForeignName
DuplicateRelation.Fields.Append fldLoop
i = i + 1
Loop
End Function
And then, when importing:
Dim colRelBackup As Collection
Set colRelBackup = DeleteRelationsGiveBackup("MyTable")
'Delete MyTable
'Import new version
RestoreRelationBackup colRelBackup
(Note that the code is quite long, developed for a project several years ago, and not extensively tested. If a field name/type is not exactly like how it was before the import, the restore of the backup might fail and the relations will be permanently lost).
So some high level architect advice: replacing data versus replacing table
It is easier replacing data - - the new incoming data must be the exact same structure as the existing table (i.e. same field names and no new fields).
just fire a Delete Query to the existing table that clears out all records
then fire an Append Query to the linked CSV file that writes all those records into the existing table
very simple really.
You can replace the tables if you must - and you are already down this path. You can delete those table relationships entirely. That table relationship feature is useful - but not mandatory. You can create relationships at the query level as an alternative. Essentially the table relationships just auto create the query level relationships. If you delete the table relationships then one must simply create the table relationships at the query level manually - they don't automatically appear. Note however that if one is relying on cascade deletes or referential integrity, then removing table relationships will undo that - so you should check these points.
Deleting Table Relationships will not break any existing queries. Their table relationship join lines will remain intact.

For Each loop for mysql database in vb.net

I'm trying to create a reminder that notifies users the number of days before a chemical expires. I'm trying to retrieve the data in my database using ForEach loop, but I can't get the syntax right.
For Each chemicalName as DataRow In chemicalinventory.Rows
For some reason, the error: name 'chemicalinventory' not declared keeps popping up.
From what I seen online, that is supposed to be the table name. Am I coding it wrong? Please answer if you know what's the error.
You cannot just directly start querying tables in this manner. You need to select your data from the database table and use it to fill a DataTable. You can then loop through the rows of this DataTable to get what you're after.
There are many ways to do that, but here is a very basic setup - granted, you'd need to specify a connection string in your Web.Config, and modify the SQL query to be relative to your needs.
Dim sqlConnection1 As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("YOUR_CONNECTION_STRING").ConnectionString)
Dim cmd As New SqlCommand
cmd.CommandType = Data.CommandType.Text
cmd.CommandText = "SELECT * FROM chemicals"
cmd.Connection = sqlConnection1
Dim DataAdapter As New SqlDataAdapter
DataAdapter.SelectCommand = cmd
Dim chemicalInventory As New DataTable()
DataAdapter.Fill(chemicalInventory)
For each row as DataRow in chemicalInventory.rows
Response.write(row.item("column_name"))
Next

Displaying specific fields in the datagrid from a MySQL search result in VB.NET

I design (PHP) db editors in the gaming world as a past time. I took up the challenge of doing the same thing, but this time with VB (originally 6, but MySQL is tricky) so I'm working with 2008.
One of the tables has a massive amount of info and I only need to display 4 or 5 fields from it as a search result (there are over 100+ fields)
I know how to populate the grid with the whole table, but do not know how to do it via specific fields without going into a very long way around it.
This is my first time from VB6 to VB.NET - sadly not too impressed (looks like they (M$) have deviated from "BASIC" and went for the C++ engine format - super ugly (but I digress).
Try
conn.Open()
da = New MySqlDataAdapter(sqlQRY, conn)
Dim cb As MySqlCommandBuilder = New MySqlCommandBuilder(da)
da.Fill(ds, "big_table")
DataGridView1.DataSource = ds
DataGridView1.DataMember = "big_table"
Catch ex As Common.DbException
MsgBox(ex.ToString)
Finally
conn.Close()
End Try
The above works fine, but I do not not need all 100+ fields displaying. Just want player name, level, if they are online and a few other fields to show - from here I can select a row and process the data elsewhere in the program.
Hope that made sense :-)
edit:
clarification: I need to know how, at run time, to create the datagrid to accept the results of my query so it does NOT display the whole record.
Is it possible you specify all fields in your query with a *? Just declare sqlQRY like:
SELECT Player_Name, Level, Online_Status, A_Few_Other_Fields FROM Players;

What could be causing a missing DB field on my Crystal Report at run-time?

Ladies & Gentlemen,
I have been, thus far, successful in programmatically pulling records from a MySQL database to create a crystal report from a single table. Using the code below, I'm trying to join two tables and display their matched records on the report:
Try
Dim myConnectionString As String = "Server=" & FormLogin.ComboBoxServerIP.SelectedItem & ";Port=3306;Uid=parts;Password=parts;Database=accounting;"
Dim dbConn As New MySqlConnection(myConnectionString)
Dim dbQuery As String = "SELECT * " & _
"FROM cc_master a JOIN customer b ON b.accountNumber = a.customer_accountNumber;"
Dim dbAdapter As New MySqlDataAdapter(dbQuery, dbConn)
Dim dbTable As New DataTable
dbAdapter.Fill(dbTable)
Dim report As New rptCardListAll
report.SetDataSource(dbTable)
CrystalReportViewer1.ReportSource = report
CrystalReportViewer1.Zoom(1)
Catch ex As Exception
'MsgBox(ex.Message)
End Try
The problem I'm running into now is that when the report runs at run-time, all the db records are populated on the report except for the one field that I'm pulling from the CUSTOMER table. Below is a screen shot. Notice the blank CUSTOMER NAME - this shouldn't be blank because I know for a fact there's data in that field for every record.
The query works fine when I run it directly on the DB using MySQL Workbench, so I can't figure out why the report won't pull the requested information. Any help would be appreciated, thanks.
EDIT: Screenshot showing DataSet Visualizer during debug containing the missing field (nameCOMPANY)
Good evening all,
So after hours of reading and searching the web, I've managed to arrive at or better yet, discover, a solution to my problem.
It appears that even though I'd created a DataSet within VS and used that to create my CR Report, I wasn't actually using that DataSet in code. Instead what I was doing was creating a new DataTable at run-time, filling that with my query result, and setting the report's datasource property to it.
What I should have been doing was to create an instance of my DataSet (the one I created earlier and used to design the report), fill it with my query result, and set the report's datasource property to it. This allowed CR to recognize and respect the table links/relationships I established earlier in the DataSet designer. I also learned that when using the DataAdapter with a query that returns multiple tables, the default naming convention is "Table" then "Table1" and so forth - that it was necessary to map these to the actual names of my tables in the DB.
So after applying all these lessons, I had to re-do my code as follows:
Dim report As New rptCardListAll
Dim myConnectionString As String = "Server=" & FormLogin.ComboBoxServerIP.SelectedItem & ";Port=3306;Uid=parts;Password=parts;Database=accounting;"
Dim dbConn As New MySqlConnection(myConnectionString)
Dim dbQuery As String = "SELECT * FROM cc_master; " & _
"SELECT * FROM customer;"
Dim dbAdapter As New MySqlDataAdapter(dbQuery, dbConn)
With dbAdapter
.TableMappings.Add("Table", "cc_master")
.TableMappings.Add("Table1", "customer")
End With
Try
Dim dbDataSet As New accountingDataSet
dbAdapter.Fill(dbDataSet)
report.SetDataSource(dbDataSet)
CrystalReportViewer1.ReportSource = report
CrystalReportViewer1.Zoom(1)
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly, "An Error Has Occured....")
End Try
My report now shows the missing field "nameCOMPANY" from the customer table.
CREDIT:
I want to thank #halfer, #luchosrock, and #EvilBob22 for their assistance. Also, I give credit to the authors in the following documents:
http://developer-content.emc.com/developer/downloads/CrystalReport_ADO_Dataset.pdf
How to fill Dataset with multiple tables?