H2 database script cannot be imported into MySQL - mysql

I have created a local H2 database which I always opened in MySQL mode to insert data. Now, I want to export it with SCRIPT, in order to import it with phpMyAdmin on a remote MySQL database on a remote server. I get the following:
SET LOCK_MODE 3;
;
CREATE USER IF NOT EXISTS SA SALT '...' HASH '...' ADMIN;
CREATE CACHED TABLE PUBLIC.RAWVALUEITEM(
LANGUAGE VARCHAR(2) NOT NULL SELECTIVITY 1,
RAWVALUE VARCHAR(40) NOT NULL SELECTIVITY 99,
STRIPPED VARCHAR(40) NOT NULL SELECTIVITY 96
);
...
Unfortunately, phpMyAdmin import is not happy:
#1193 - Unknown system variable 'LOCK_MODE'
When I manually remove the set instruction, I get further errors:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NOT EXISTS SA SALT '...' HASH '...' at line 1
The code I use to export the database as a script is:
public static final String DB_DIR_LOCATION = "E:/Temp/FWDB/";
public static final String H2_CONNECTION = "jdbc:h2:file:"
+ DB_DIR_LOCATION + "FWDB_PHP_TEST" + "Mode=MySQL;IFEXISTS=TRUE";
public static void main(String[] args) throws SQLException {
Connection conn = DriverManager.
getConnection(H2_CONNECTION, "sa", "");
PreparedStatement ps;
ps = conn.prepareStatement("SCRIPT TO 'E:/Temp/FWDB/FWDB_EXPORT.gz' "
+ "COMPRESSION GZIP");
ps.execute();
}
How can generate a script from my DB which will be imported successfully by phpMyAdmin on my remote server?

The SQL script generated by the SCRIPT TO command is not cross-platform. A better solution might be to use a database tool such as the SQuirreL DB Copy Plugin or another database tool.

Related

MySQL Syntax with FROM with a var

I got some problems with my MySQL Syntax.
This is my code:
Config.SocietyMoneyTable = 'addon_account_data'
local result = MySQL.Sync.fetchAll("SELECT money FROM #account_table WHERE account_name = #society", {
['#account_table'] = Config.SocietyMoneyTable,
['#society'] = society
})
Error:
[ERROR] [MySQL] [maze_management] An error happens on MySQL for query "SELECT money FROM
'addon_account_data' WHERE account_name = 'society_police'": ER_PARSE_ERROR: You have an
error in your SQL syntax; check the manual that corresponds to your MariaDB server version
for the right syntax to use near ''addon_account_data' WHERE account_name = 'society_police''
at line 1
The Syntax does work when I change the #account_table to the string which is in Config.SocietyMoneyTable. But I need this configed so this is no solution for me.
A query parameter annotated with the # sigil can only be used in place of a scalar value, not a table name or other identifier. You need to use string formatting to get your configurable table name into the query, not a query parameter.
Something like the following:
Config.SocietyMoneyTable = 'addon_account_data'
local queryString = string.format("SELECT money FROM `%s` WHERE account_name = #society",
Config.SocietyMoneyTable)
local result = MySQL.Sync.fetchAll(queryString, {
['#society'] = society
})
I have not tested this code, and I don't use Lua often, so if there are mistakes I will have to leave it to you to resolve them. But it should at least show the principle: identifiers (like table names) must be fixed in the query string, not added as query parameters.

How to create table with DATETIME DEFAULT using Java (JDBC, MySQL)

I have some MySQL scripts that are needed for recreating a database. They work fine when I execute them on the command line using the mysql command.
Now I wrote a Java class that should execute these scripts using a JDBC connection to the MySQL database.
One line in a "create table"-statement in the script is:
registration_date DATETIME DEFAULT CURRENT_TIMESTAMP
This line however won't be executed using the JDBC-MySQL connection. I get the error:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Invalid default value for 'registration_date'
The relevant method is shown below. sqlScriptPathpoints to the folder containing the sql scripts. The connectionString has this content: "jdbc:mysql://localhost:3306/testDb?useUnicode=yes&characterEncoding=UTF-8&allowMultiQueries=true"
public static void recreate(String connectionString, String dbUser, String dbPass, String sqlScriptPath) throws Exception {
// Find and filter sql scripts
File file = new File(sqlScriptPath);
File[] scripts = file.listFiles(new FileFilter() {
#Override
public boolean accept(File file) {
return file.getName().endsWith(".sql");
}
});
List<File> scriptsList = Arrays.asList(scripts);
Collections.sort(scriptsList);
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection conn = DriverManager.getConnection(connectionString, dbUser, dbPass);
// Load each script and apply it
for (File f : scriptsList) {
System.out.println("Importing script: " + f);
List<String> lines = Files.readAllLines(Paths.get(f.getAbsolutePath()), Charset.forName("UTF-8"));
StringBuilder sb = new StringBuilder();
for (String line : lines) sb.append(line).append("\n");
String sqlStatement = sb.toString();
System.out.print(sqlStatement);
Statement st = conn.createStatement();
st.execute(sqlStatement);
st.close();
}
}
And the relevant part of the script:
CREATE TABLE user
(
id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
username VARCHAR(255),
password VARCHAR(255),
age_group INT,
registration_date DATETIME DEFAULT CURRENT_TIMESTAMP
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8;
What is the problem here?
I inherited a Java test harness for a MySQL database that was failing with this error on a datetime column defined as NOT NULL with no default defined. I added DEFAULT NOW() and it worked fine after that.

Run script with EntityManager JPA on Mysql

I'm trying to run a script (.sql file) but i have multiples errors since i tried many ways, here's my main sql script:
INSERT INTO `Unity` VALUES (11,'paq',0,'2013-04-15 11:41:37','Admin','Paquete','Paq',0,'2013-04-15 11:41:37','AAA010101AAA',NULL);
INSERT INTO `product` VALUES (11,'chi','USD','chi one',0,'2013-04-15 11:42:13',0,'Admin','Chi name',0.25,0,15,'2013-04-15 11:42:13','AAA010101AAA',NULL);
and here's my main dao code:
#Autowired
private EntityManager em;
#Override
public Integer runSql(String path) {
try {
Archivo archivo = new Archivo();
String strQuery = archivo.readFileText(path);
Query query = em.createNativeQuery(strQuery);
return query.executeUpdate();
} catch (IOException e) {
e.printStackTrace();
return 0; //TODO return false;
}
}
If i run the script with only one Insert it runs ok, but when my script has more than 1 insert i get the following Exception:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'INSERT INTO producto_servicio VALUES (11,'chi','USD','chi
one',0,'2013-04-15 11:42:13',0,'' at line 2
Is there a way to run a script file with multiple inserts?
I also tried with BEGIN, and END, and START TRANSACTION AND COMMIT, but with no good results.
Thank you for the help :)
You can't execute the script by the em.createNativeQuery, as i know.
You should to split the script into statements and execute them one by one.
You may use ScriptRunner. It can be used separately from the MyBatis.
Example:
em.getTransaction().begin();
Connection connection = em.unwrap(Connection.class);
ScriptRunner sr = new ScriptRunner(connection);
sr.runScript(new StringReader("INSERT INTO `Unity` VALUES (11,'paq',0,'2013-04-15 11:41:37','Admin','Paquete','Paq',0,'2013-04-15 11:41:37','AAA010101AAA',NULL);\r\nINSERT INTO `product` VALUES (11,'chi','USD','chi one',0,'2013-04-15 11:42:13',0,'Admin','Chi name',0.25,0,15,'2013-04-15 11:42:13','AAA010101AAA',NULL);"));
em.getTransaction().commit();

send data from mysql to MS-SQL database

I have a table name student with fields, name and roll in my-sql database. Also, I have a same table name student in MS-SQL database with the fields, name and roll.
When a value inserted into my MySQL database student table, I need to auto-insert the same value into the MS-SQL database student table.
Why are you using two separate databases to do the same thing? can't you just choose one?
If you are just trying to export and import data you should be able to export as a csv from one database and import into the other, and then only use the database you need to.
If not i suppose you could write a class that wraps around two database objects and actually executes every query on both databases.
for example:
public class database
{
public DbConnection mySqlConnection;
public DbConnection sqlConnection;
/// <summary>
/// open two db connections
/// </summary>
public database()
{
mySqlConnection =//string that will open the mysql
mySqlconnection = //insert string will open the sql server database
}
public excecuteNonQuery(String SQL)
{
//cmd1 = mysql command
//cmd2 = mssql command
cmd1.excecute(SQL);
cmd2.execute(SQL);
}
}
And just create functions that handle preparing the commands and inserting the data, so that the operations are performed at the same time on both of the databases. I'm not aware of any method of replicating a mysql database to a mssql database.
You could have a cron that runs every so often to insert records it hasn't seen yet.
// Assuming the primary key is an id int auto_increment
startId = getLastIdFromPreviousRun();
lastId = 0;
offset = 0;
while(true) {
mysqlrs = mysqlQuery(
"SELECT * FROM users WHERE id > ? ORDER BY id LIMIT ?, 1000",
startId,
offset
);
if (!mysqlrs || mysqlrs.count() == 0)
break;
foreach(mysqlrs as mysqlrow) {
mssqlInsert('users', mysqlrow);
lastId = mysqlrow['id'];
}
offset += 1000;
}
if (lastId) {
setLastIdForNextRun(lastId);
}

I need to write an Access 97 .mdb file

I need to export data from a SQL server 2005 DB to an Access 97 .mdb file. The client that needs it, needs it to be Access 97 because the system that they're importing it into requires Access 97 file format (don't get me started). Any suggestions how to write an old-timey Access file from SQL or .Net (or VB6 or Ruby or Python..)?
Thanks in advance,
Lee
I'd let Sql 2005 do it for you.
In the Sql Management Stuidio, right-click on your source database, then Tasks, then Export Data. You can use this to export directly into your Access database, just follow the prompts. Or you can output it to a file format you can use to put into Access.
What you need to do is export into an Access file for whatever Access version you have installed (as long as it's 2000...2003; Access 2007 can't write to Access 97 files). I assume you already know how to do this.
Then you can create an Access object via COM and ask it to convert your new .mdb file into a new Access 97 database. In VBScript, the code looks like this (adjust as necessary if you're using VBA, VB.Net, or another language):
const acFileFormatAccess97 = 8
dim app
set app = CreateObject("Access.Application")
app.ConvertAccessProject "y:\mydatabase.mdb", "y:\mydatabase97.mdb", acFileFormatAccess97
If you have Access 97 installed, the above command won't work, because Access didn't have the ConvertAccessProject function in that version. Of course, you don't need to convert the file in that case anyway.
This might give you a starting point.
And this article is a bit old, but you might be able to pick up something. I can only find those using Jet 4.0 which is compatible w/ Access 2000 as in the previous article. Using the MS Access driver might give you what you want.
After you created the database, use regular ODBC / OLE DB related stuffs in ADO.NET to create your table and populate them w/ your data.
This is a great question! I've actually wanted to be able to do this kind of thing in a programmatic way, but in the past I've had nothing but trouble coming up with it. However, have matured a bit in my .NET skills over the years, I thought I would take a shot at writing a solution that could be executed as a Console app. This can be implemented either as a scheduled task on the windows server or sql server (using the Sql Server agent). I don't see why this couldn't be automated from the Sql Server without the following code, but I really had fun with this, so I just have to put it out there. The table in both Sql and Access is a list of dogs, with an ID, a name, a breed, and a color. Generic stuff. This actually works on my desktop between a local instance of Sql Server and Access (2007, but I don't know why it wouldn't work with 97). Please feel free to critique.
BTW, has the following:
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
Here:
static void Main(string[] args)
{
SqlConnectionStringBuilder cstrbuilder = new SqlConnectionStringBuilder();
cstrbuilder.DataSource = "localhost";
cstrbuilder.UserID = "frogmorton";
cstrbuilder.Password = "lillypad99";
cstrbuilder.InitialCatalog = "Dogs";
SqlConnection sconn = new SqlConnection(cstrbuilder.ToString());
sconn.Open();
SqlCommand scmd = new SqlCommand("select * from Dogs", sconn);
SqlDataReader reader = scmd.ExecuteReader();
if (reader.HasRows)
{
OleDbConnectionStringBuilder sb = new OleDbConnectionStringBuilder();
sb.Provider = "Microsoft.Jet.OLEDB.4.0";
sb.PersistSecurityInfo = false;
sb.DataSource = #"C:\A\StackOverflog\DogBase.mdb";
OleDbConnection conn = new OleDbConnection(sb.ToString());
conn.Open();
OleDbCommand cmd = new OleDbCommand("Delete from Dogs", conn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
conn.Close();
OleDbConnection conn2 = new OleDbConnection(sb.ToString());
conn2.Open();
OleDbCommand icmd = new OleDbCommand("Insert into dogs (DogID, DogName, Breed, Color) values ({0}, '{1}', '{2}', '{3}');", conn2);
icmd.CommandType = CommandType.Text;
while (reader.Read())
{
string insertCommandString =
String.Format("Insert into dogs (DogID, DogName, Breed, Color) values ({0}, '{1}', '{2}', '{3}');"
, reader.GetInt32(0)
, reader.GetString(1)
, reader.GetString(2)
, reader.GetString(3)
);
icmd.CommandText = insertCommandString;
icmd.ExecuteNonQuery();
}
conn2.Close();
}
sconn.Close();
}
The best way to do this is via PInvoke You will need to pass the CREATE_DBV3 parameter to SqlConfigDataSource(). Here is the code taken from JetSqlUtil.cs of my OSS Project PlaneDisaster.NET:
#region PInvoke
private enum ODBC_Constants : int {
ODBC_ADD_DSN = 1,
ODBC_CONFIG_DSN,
ODBC_REMOVE_DSN,
ODBC_ADD_SYS_DSN,
ODBC_CONFIG_SYS_DSN,
ODBC_REMOVE_SYS_DSN,
ODBC_REMOVE_DEFAULT_DSN,
}
private enum SQL_RETURN_CODE : int
{
SQL_ERROR = -1,
SQL_INVALID_HANDLE = -2,
SQL_SUCCESS = 0,
SQL_SUCCESS_WITH_INFO = 1,
SQL_STILL_EXECUTING = 2,
SQL_NEED_DATA = 99,
SQL_NO_DATA = 100
}
[DllImport("ODBCCP32.DLL",CharSet=CharSet.Unicode, SetLastError=true)]
private static extern int SQLConfigDataSource (int hwndParent, ODBC_Constants fRequest, string lpszDriver, string lpszAttributes);
[DllImport("ODBCCP32.DLL", CharSet = CharSet.Auto)]
private static extern SQL_RETURN_CODE SQLInstallerError(int iError, ref int pfErrorCode, StringBuilder lpszErrorMsg, int cbErrorMsgMax, ref int pcbErrorMsg);
#endregion
internal static string GetOdbcProviderName()
{
if (string.IsNullOrEmpty(OdbcProviderName))
{
var odbcRegKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\ODBC\\ODBCINST.INI\\ODBC Drivers", false);
var drivers = new List<string>(odbcRegKey.GetValueNames());
if (drivers.Contains("Microsoft Access Driver (*.mdb, *.accdb)"))
{
OdbcProviderName = "Microsoft Access Driver (*.mdb, *.accdb)";
}
else if (drivers.Contains("Microsoft Access Driver (*.mdb)"))
{
OdbcProviderName = "Microsoft Access Driver (*.mdb)";
}
else
{
//TODO: Condider checking for 32 versus 64 bit.
//TODO: Find a better exception type. http://stackoverflow.com/questions/7221703/what-is-the-proper-exception-to-throw-if-an-odbc-driver-cannot-be-found
throw new InvalidOperationException("Cannot find an ODBC driver for Microsoft Access. Please download the Microsoft Access Database Engine 2010 Redistributable. http://www.microsoft.com/download/en/details.aspx?id=13255");
}
}
/// <summary>
/// Creates an Access 2003 database. If the filename specified exists it is
/// overwritten.
/// </summary>
/// <param name="fileName">The name of the databse to create.</param>
/// <param name="version">The version of the database to create.</param>
public static void CreateMDB (string fileName, AccessDbVersion version = AccessDbVersion.Access2003) {
;
if (File.Exists(fileName)) {
File.Delete(fileName);
}
string command = "";
switch (version)
{
case AccessDbVersion.Access95:
command = "CREATE_DBV3";
break;
case AccessDbVersion.Access2000:
command = "CREATE_DBV4";
break;
case AccessDbVersion.Access2003:
command = "CREATE_DB";
break;
}
string attributes = String.Format("{0}=\"{1}\" General\0", command, fileName);
int retCode = SQLConfigDataSource
(0, ODBC_Constants.ODBC_ADD_DSN,
GetOdbcProviderName(), attributes);
if (retCode == 0)
{
int errorCode = 0 ;
int resizeErrorMesg = 0 ;
var sbError = new StringBuilder(512);
SQLInstallerError(1, ref errorCode, sbError, sbError.MaxCapacity, ref resizeErrorMesg);
throw new ApplicationException(string.Format("Cannot create file: {0}. Error: {1}", fileName, sbError));
}
}
If you need to do this from a 64 bit version of SQL server you will need the 64 bit version of Office 2010 or the Microsoft Access Database Engine 2010 Redistributable installed.
I think it's crazy to do it from SQL Server. Just create an ODBC DSN for your SQL Server and import the tables into your Access 97 MDB and be done with it. The only reason you might want to do it otherwise is if you want to automate it and do it repeatedly, but that can be automated in Access, too (TransferDatabase can do ODBC imports), and will take only as many lines of code as there are tables to import.