Updating an HSQLDB table from Eclipse - java

I'm currently using Java to access a .sql file (called patient.sql). Running queries and updating the table works well while the program is running, but the changes aren't made on disk.
So, for example, I have a 30 node database with some fields including caseID (primary key) and Hospital. I want to change the Hospital of the node with caseID = Case29. To do this, I use the following code:
// Prepare a statement to update a record
String sql = "UPDATE patient SET Hospital='CX' WHERE caseID = 'Case29'";
// Execute the insert statement
stmt.executeUpdate(sql);
I have checked this and seen that it works (using a quick System.out.println()). However, when I finish the program and open the patient.sql, my change has not been registered. How can I save this change made?
Cheers
EDIT: I'm using HSQLDB

If you are using HSQLDB changes are stored in a .log file until SHUTDOWN is called.
After a SHUTDOWN, all changes are moved to a .script file.
One description of HSQLDB files here:
http://hsqldb.org/doc/guide/ch01.html
In your case I suspect no SHUTDOWN has been called.

Related

SQLite “after update” trigger in Android does not appear to run after every record update

QUESTION:
What, if anything, could cause an SQLite trigger to only run some of the time?
SUMMARY: I'm getting seemingly inconsistent results from a new trigger I've written in SQLite and I'd like to understand if this is happening because I've made a mistake in my SQL/Java code or if I've possibly encountered a rare scenario where SQL triggers may not work as expected.
DETAILS:
While working on an Android project I have encountered what I originally perceived to be a problem with an SQLite trigger. However, since my new trigger exactly matches several other working triggers in the same project (except for the table names) I am beginning to wonder if my Java code is the issue instead.
The purpose of the trigger I am having trouble with is to monitor changes to TableA, such as the addition of a value in the DismissDateUTC column for example. When an update is made to any data in TableA, the trigger is supposed to put the ID of that updated TableA record into TableAChanges which is later used to determine which records were updated and should be sent back to a web server.
When using the database inspector (in Android Studio v4.2.1) or the program “DB Browser for SQLite” and running an update query on TableA manually, the trigger works exactly as expected and records appear in TableAChanges. When I make updates to TableA programmatically, the trigger does not appear to run. I believe it is not running because no records are written to TableAChanges after updates have been written to TableA.
Things I have tried so far:
Running the app on an Android 7.1.1 device (trigger is NOT working)
Running the app on an Android 8.1.0 device (trigger is NOT working)
Running the app on an Android 11 device (trigger is NOT working)
Running manual update query on TableA from Android Studio DB Inspector (trigger IS working)
Running manual update query on TableA from DB Browser for SQLite (trigger IS working)
Running manual update query on TableA from Android Debug Database by “amitshekhar” (trigger IS working)
The Tables and Trigger SQL:
CREATE TABLE TableA (
ID INTEGER PRIMARY KEY NOT NULL
-- (more table columns) --
, DismissDateUTC TEXT NULL
);
CREATE TABLE TableAChanges (
ID INTEGER PRIMARY KEY NOT NULL
);
CREATE TRIGGER trigTableA_U AFTER UPDATE ON TableA
BEGIN
REPLACE INTO TableAChanges(ID)
SELECT old.ID;
END
The Android Java in the TableA DAO class:
public boolean saveChanges() {
boolean ret = true;
ContentValues cv = new ContentValues();
cv.put("ID", mId);
// (more table columns)
cv.put("DismissDateUtc", mDismissDateUtc);
SQLiteDatabase db = DB.getInstance().getWritableDatabase();
try {
db.replaceOrThrow("TableA", null, cv);
} catch (SQLException e) {
ExceptionDao.logToAcra(e);
ret = false;
} finally {
db.close();
}
return ret;
}
*** In the interest of transparency, I am already aware that I can work around this issue by manually writing records to TableAChanges. However, I still wanted to post this question here because I am hoping to gain an understanding of the cause of this issue rather than ignoring the issue.
The reason that the trigger does not work is because it is an AFTER UPDATE trigger, which means that it will work only after the table is updated.
On the other hand, replaceOrThrow() does not update the table.
It is actually executing an INSERT OR REPLACE INTO... or simply REPLACE INTO... statement which either inserts a new row in the table if the new ID does not already exist in the table, or if it exists, deletes the row that contains the existing ID and inserts the new row.

Can't get existing table from embedded hsqldb

To use embedded database I have created hsqldb database connected with java by this tutorial.
In general it is about creating simple table with 3 records through hsqldb manager and connect to this database with java.
Database was created and after exit the manager and connect again I gained my tables. They are recorded in test.script file.
If I try to connect with java by
connection = DriverManager.getConnection("jdbc:hsqldb:file:/db/test;ifexists=true", "SA", "");
then I got connection and can read all tables from it by
resultSet = statement.executeQuery("SELECT TABLE_NAME, COLUMN_NAME, TYPE_NAME, COLUMN_SIZE, DECIMAL_DIGITS, IS_NULLABLE FROM INFORMATION_SCHEMA.SYSTEM_COLUMNS WHERE TABLE_NAME NOT LIKE 'SYSTEM_%'");
But I can't get previous created table in manager even if script file contains that table.
This snippet of create table is placed in test.script file:
CREATE MEMORY TABLE PUBLIC.SALARYDETAILS(EMPID VARCHAR(6) PRIMARY KEY,SALARY INTEGER NOT NULL,BONUS INTEGER NOT NULL,INCREMENT INTEGER NOT NULL)
I was confused by MEMORY command, but maybe it is not what I should to fix. After remove it manager add it there again.
----- update 1 -----
SHUTDOWN command didn't help.
I don't know how HSQLDB store data, but thought that when they are in script file, it is done.
Exception what is see in the command line when running Java is
user lacks privilege or object not found
----- update 2 -----
I have created a table in Java and record data into it and I was available to get these data, but can't see it in the manager. It seems to me like different database, but location is same.
Script file doesn't contain new table and data. I don't know where data are stored.
It seems the database file was not saved. Before you exit the manager, execute this SQL command:
SHUTDOWN

Java Connection String to query from two database

I am having a problem. I have a query that checks one database table and updates another database table. I am using MySQL 5.1
UPDATE dldd.temp,test.temp
SET test.temp.name = dldd.temp.word
WHERE dldd.temp.id = test.temp.id
this is my SQL statement that is working fine. Now I want to execute this statement using Java PreparedStatement . The problem is I don't know how to write the Connection String to select two database i.e
"jdbc:mysql://localhost:3306/"+dbname+"?characterEncoding=UTF-8"
What should come in place of dbname. Can I select multiple db there.
Have a look at http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html.
If the database is not specified, the connection is made with no default database. In this case, either call the setCatalog() method on the Connection instance, or fully specify table names using the database name (that is, SELECT dbname.tablename.colname FROM dbname.tablename...) in your SQL. Opening a connection without specifying the database to use is generally only useful when building tools that work with multiple databases, such as GUI database managers.

Change Table names in derby database using entitymanager

I am using an APACHE DERBY database, and basing my database interactions on EntityManager, and I don't want to use JDBC class to build a query to change my tables' names (i just need to put a prefix to each new user to the application, but have the same structure of tables), such as:
//em stands for EntityManager object
Query tableNamesQuery= em.createNamedQuery("RENAME TABLE SCHEMA.EMP_ACT TO EMPLOYEE_ACT");
em.executeUpdate();
// ... rest of the function's work
// The command works from the database command prompt but i don't know how to use it in a program
//Or as i know you can't change system tables data, but here's the code
Query tableNamesQuery= em.createNamedQuery("UPDATE SYS.SYSTABLES SET TABLENAME='NEW_TABLE_NAME' WHERE TABLETYPE='T'");
em.executeUpdate();
// ... rest of the function's work
My questions are :
This syntax is correct?
Will it work?
Is there any other alternative?
Should I just use the SYS.SYSTABLES and find all the tables that has 'T' as tabletype and alter their name their, will it change the access name ?
I think you're looking for the RENAME TABLE statement: http://db.apache.org/derby/docs/10.10/ref/rrefsqljrenametablestatement.html
Don't just issue update statements against the system catalogs, you will corrupt your database.

Mysql Copy Database From Sql Statement

I am attempting to create a test database (based off of my production db) at runtime, but rather than have to maintain an exact duplicate test db i'd like to copy the entire data structure of my production db at runtime and then when I close the test database, drop the entire database.
I assume I will be using statements such as:
CREATE DATABASE test //to create the test db
CREATE TABLE test.sampleTable LIKE production.sampleTable //to create each table
And when I am finished with the test db, calling a close method will run something like:
DROP DATABASE test //delete the database and all its tables
But how do I go about automatically finding all the tables within the production database without having to manually write them out. The idea is that I can manipulate my production db without having to be concerned with maintaining the structure identically within the test db.
Would a stored procedure be necessary in this case? Some sample code on how to achieve something like this would be appreciated.
If the database driver you are using supports it, you can use DatabaseMetaData#getTables to get the list of tables for a schema. You can get access to DatabaseMetaData from Connection#getMetaData.
In your scripting language, you call "SHOW TABLES" on the database you want to copy. Reading that result set a row at a time, your program puts the name of the table into a variable (let's call it $tablename) and can generate the sql: "CREATE TABLE test.$tablename LIKE production.$tablename". Iterate through the result set and you're done.
(You won't get foreign key constraints that way, but maybe you don't need those. If you do, you can run "SHOW CREATE TABLE $tablename" and parse the results to pick out the constraints.)
I don't have a code snippet for java, but here is one for perl that you could treat as pseudo-code:
$ref = $dbh->selectall_arrayref("SHOW TABLES");
unless(defined ($ref)){
print "Nothing found\n";
} else {
foreach my $row_ref (#{$ref}){
push(#tables, $row_ref->[0]);
}
}
The foreach statement iterates over the result set in an array reference returned by the database interface library. The push statement puts the first element of the current row of the result set into an array variable #tables. You'd be using the database library appropriate for your language of choice.
I would use mysqldump : http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html
It will produce a file containing all the sql commands needed to replicate the prod database
The solutions was as follows:
private static final String SQL_CREATE_TEST_DB = "CREATE DATABASE test";
private static final String SQL_PROD_TABLES = "SHOW TABLES IN production";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute(SQL_CREATE_TEST_DB);
SqlRowSet result = jdbcTemplate.queryForRowSet(SQL_PROD_TABLES);
while(result.next()) {
String tableName = result.getString(result.getMetaData().getColumnName(1)); //Retrieves table name from column 1
jdbcTemplate.execute("CREATE TABLE test2." + tableName + " LIKE production." + tableName); //Create new table in test2 based on production structure
}
This is using Spring to simplify the database connection etc, but the real magic is in the SQL statements. As mentioned by D Mac, this will not copy foreign key constraints, but that can be achieved by running another SQL statement and parsing the results.

Categories