I’m trying to use a ‘SELECT *’ statement to grab a record from one Host.database.table, and insert it into a DifferentHost.database.table. The following works GREAT (and side-steps issues with auto-generated Pkey-IDs), but only when copying across the same Host:
Var xDB As MySQLCommunityServer = New MySQLCommunityServer
// more setup here (left out for brevity)
xDB.ExecuteSQL("INSERT INTO <dbase_name_here>.tmptable_1 SELECT * FROM <another_database>.<identical_table_design> WHERE id = 123;)
xDB.ExecuteSQL("UPDATE <dbase_name_here>.tmptable_1 SET id = NULL;")
xDB.ExecuteSQL("INSERT INTO <dbase_name_here>..<identical_table_design> SELECT * FROM <dbase_name_here>.tmptable_1;")
xDB.ExecuteSQL("DROP TEMPORARY TABLE IF EXISTS <dbase_name_here>.tmptable_1;")
xDB.CommitTransaction
xDB.Close
The same User and Credentials work for connecting to both Hosts, Databases, and their Tables. Obviously the “xDB” variable is a single connection to a single host, which is where I’m struggling.
I’m really hoping to streamline my code by using a “INSERT INTO” combined with “SELECT * FROM” and not have to hard-code Vars and field names.
Is there a best-practices means of copying a record from one host and inserting it into another? (thanks!)
If you want the MySQL sever to connect to a foreign database, the search term you are looking for is FEDERATED TABLE
Federated tables provide a view on data residing in a separate instance of MySQL, whether on the same host or an entirely different host. To connect to a different host the transport needs to be in place to allow it.
Federated tables and streamlined do not fit easily in the same sentence. Unless you have a compelling reason to keep it server side, it may be easier to manage two connections at the client.
Hi Matthew, thanks for the feedback!
The databases are located across the shop floor, and the (xojo) Service app has to grab data from these points, and save selected rows back to another centralized database for more fun.
Using the advice to manage two connections I have a follow-on question…
I’m now using the Rowset acquired from the 1st dbase query and then opening a 2nd connection to send a new insert statement to the central dbase. However, I’m not easily finding syntax to allow me to do something like “INSERT INTO mydatabase SELECT * myRowSet”.
I can go thru the pains of building a loooong SQL insert statement, but that’s a lot of hand-coding for each “param_1 = (rows.Column(“PARAM_NAME_XYZ”))”.
Anyone know a easier way to iterate thru a RowSet (single Row) and insert it in-whole into a like-for-like table?
Does Xojo’s IdxField fit the bill? Allows a loop to iterate fields by numerical position.
Also, if you need the foreign schema to create a temporary table, there is the MySQL, SHOW CREATE TABLE
Unsure, but…
Var xDB As MySQLCommunityServer = New MySQLCommunityServer
xDB is used to read from a database and also to write to the other database ?
Hi Emile, I’m using one ‘xDB’ to connect to datasource #1, grabbing a Rowset, closing the connection, opening another ‘xDB’ (MySQLCommunityServer) connection to datasource #2, and wanting to find the simplest way to inject this record into a Table in #2 (that has an identical schema).
As Matthew pointed out there’s ways to iterate thru the Rowset, however that’d mean I’d have to have an (iterable?) means of inserting the data into a ‘INSERT’ statement, which is where I’m stuck now.
Maybe this will help get you started?
Var sourceDb As New Database
Var sqlInsert As String, sqlValues As String, sqlValue As String
Var maxIdx As Integer, fieldNames As String
Var doInsert As Boolean, idx As Integer
Var rs As RowSet = sourceDb.SelectSQL("SELECT * FROM myTable;")
If Not (rs Is Nil) Then
If Not (rs.BeforeFirstRow And rs.AfterLastRow) Then
doInsert = True
maxIdx = rs.ColumnCount -1
//assemble field names
For idx = 0 To maxIdx
fieldNames = fieldNames + "'" + rs.ColumnAt(idx).Name + "',"
Next
//trim the last comma
//assemble values
For idx = 0 To maxIdx
sqlValue = rs.ColumnAt(idx)
If Not (IsNumeric(sqlValue)) Then
sqlValues = sqlValues + "'" + sqlValue + "'"
Else
sqlValues = sqlValues + sqlValue
End If
sqlValues = sqlValues + ","
Next
//trim the last comma
fieldNames = fieldNames.Left(fieldNames.Length -1)
sqlValues = sqlValues.Left(fieldNames.Length -1)
//assemble insert statement
sqlInsert = "INSERT INTO myTable(" + fieldNames + ") VALUES(" + sqlValues + ");"
End If
End If
//insert into target
Try
If doInsert Then
Var targetDb As New Database
targetDb.ExecuteSQL sqlInsert
End If
Catch DatabaseException
End Try
I love this strategy - it’s totally reusable as well. I’ll give it a go!