HSQLDB INSERT Value in a Database - java

Hi i have a Problem while inserting data in my databases ...
String query = "INSERT INTO gutscheine (code, Wert) values ("+Code+","+Wert+")";
SQLConnection sql = new SQLConnection("Gutscheine.db");
PreparedStatement ps;
try {
ps = sql.con.prepareStatement(query);
int i = ps.executeUpdate();
if (i == -1) {
System.out.println("db error : " + query);
}
} catch (SQLException e) {
e.printStackTrace();
}
sql.CloseConnection(); // my own funktion
My Error:
java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: GUTSCHEINE
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
at com.daniel.guthaben.Gutschein.<init>(Gutschein.java:33)
at com.daniel.guthaben.Main.main(Main.java:7)
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: GUTSCHEINE
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.SchemaManager.getTable(Unknown Source)
at org.hsqldb.ParserDQL.readTableName(Unknown Source)
at org.hsqldb.ParserDQL.readRangeVariableForDataChange(Unknown Source)
at org.hsqldb.ParserDML.compileInsertStatement(Unknown Source)
at org.hsqldb.ParserCommand.compilePart(Unknown Source)
at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
at org.hsqldb.Session.compileStatement(Unknown Source)
at org.hsqldb.StatementManager.compile(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 4 more
Here i am trying adding context from the root user ... (on the left you can see the table exists)
http://i.stack.imgur.com/FS5ws.png
Sorry I was using diffrent databases ... :(

it's generally not advised to use string building for your query. String query = "INSERT INTO gutscheine (code, Wert) values (?, ?)"; and then running it through a safe query preparation is going to be better.
That said, the error sounds pretty obvious? user lacks privilege or object not found: GUTSCHEINE. Doesn't look like you're connecting as a particular user from your code, so I suspect you forgot to pass along your username and password when setting up the database connection. If that part's fine, verify Gutscheine.db exists.

The problem here is simple. When you are inserting string values, you need to enclose them in single quotes.
For example, "insert into table(col1, col2) values ('ABC','xyz');"
Have a look at the example provided in this link:
https://www.tutorialspoint.com/hsqldb/hsqldb_insert_query.htm
In your case, you need to enclose the values of Code and Wert in single quotes before you insert, or at the time of insert.
The following approach worked for me:
Code = "'" + Code + "'";
Wert = "'" + Wert + "'";
Use your insert query now, and it should work.

Even though hsql is quite forgiving and requires no infrastructure, you need to create the table upfront - e.g.
CREATE TABLE Gutscheine ( code varchar 20, Wert varchar 20 )
Also, you might want to read about SQL-Injection and use PreparedStatement. While you're at it, google for "little bobby tables"
I haven't run into privilege issues with hsql yet, but you might want to check how you open the connection, e.g. if you give a proper user account. You can actually check a proper one by looking at the hsql storage, which is clear text. It should contain the required user name - e.g. "SA"
Also, with that error message on google, several threads come up that suggest that hsql version upgrade might help, or that you ended up with a corrupt database after not executing "SHUTDOWN;" after creation of the database. Another one is the database name "null" in your .script file. Well, check them for yourself and try which solution matches your problem (the two linked threads point to several possible solutions):
http://sourceforge.net/p/hsqldb/mailman/message/28944633/
http://www.coderanch.com/t/460394/JDBC/databases/HSQLDB-user-lacks-privilege-object

Related

UCanAccess exception on open connection - UNIQUE constraint does not exist on referenced columns

I am trying to create a very simple connection to an access database (.accdb) in my java maven project using ucanaccess. The database is an external database and I just need to read the content of some tables for a migration task. I don't want to and shouldn't modify the tables or write anything in the database.
The java code, that I used is totally simple:
try (Connection connection = DriverManager.getConnection(databaseURL);) {
} catch (SQLException ex) { ex.printStackTrace(); }
But the connection fails right at the beginning with the following exception:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::5.0.0 a UNIQUE constraint does not exist on referenced columns: T1 in statement [ALTER TABLE T2 ADD CONSTRAINT "T2{2EB41B92-C3AB-4A64-A53C-B83095D76202}" FOREIGN KEY (C2) REFERENCES T1 (C1) ]
at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:231)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:251)
at myproject.Application.main(Application.java:42)
Caused by: java.sql.SQLSyntaxErrorException: a UNIQUE constraint does not exist on referenced columns: T1 in statement [ALTER TABLE T2 ADD CONSTRAINT "T2{2EB41B92-C3AB-4A64-A53C-B83095D76202}" FOREIGN KEY (C2) REFERENCES T1 (C1) ]
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
at net.ucanaccess.converters.LoadJet.exec(LoadJet.java:1510)
at net.ucanaccess.converters.LoadJet.access$000(LoadJet.java:74)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadForeignKey(LoadJet.java:695)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableFKs(LoadJet.java:918)
at net.ucanaccess.converters.LoadJet$TablesLoader.recreate(LoadJet.java:807)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:877)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:871)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTableData(LoadJet.java:837)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTablesData(LoadJet.java:1029)
at net.ucanaccess.converters.LoadJet$TablesLoader.loadTables(LoadJet.java:1077)
at net.ucanaccess.converters.LoadJet$TablesLoader.access$3200(LoadJet.java:264)
at net.ucanaccess.converters.LoadJet.loadDB(LoadJet.java:1579)
at net.ucanaccess.jdbc.UcanaccessDriver.connect(UcanaccessDriver.java:218)
... 3 more
Caused by: org.hsqldb.HsqlException: a UNIQUE constraint does not exist on referenced columns: T1
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.TableWorks.checkCreateForeignKey(Unknown Source)
at org.hsqldb.TableWorks.addForeignKey(Unknown Source)
at org.hsqldb.StatementSchema.getResult(Unknown Source)
at org.hsqldb.StatementSchema.execute(Unknown Source)
at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
at org.hsqldb.Session.executeDirectStatement(Unknown Source)
at org.hsqldb.Session.execute(Unknown Source)
... 18 more
I tried to make my connection "readonly", so that it doesn't check for this constraint and doesn't throw an exception. But I didn't have any success.
try (Connection connection = DriverManager.getConnection(databaseURL + ";readonly=true");) {
} catch (SQLException ex) { ex.printStackTrace(); }
Is there any way to turn off this constraint check, while creating the connection for reading some tables?
I can't post the database for reproducing the issue! Because it is a very complex database with many tables and relationships and it doesn't belong to me. I am not allowed to share it (even without data) because of General Data Protection Regulation.
Furthermore I didn't want to change anything in the database, therefore I wanted to turn off the constraint checks to be able to just connect to the database and just READ the rows of some tables.
At the end I made a copy of the database and delete all the relationships between the tables and the code could then connect to the db,
BUT:
IT TOOK 30 MINUTES TO CONNECT!!!! So, even if, I would have managed to make a copy from the database and delete all relationships between all tables each time I want to run my code (which actually isn't possible in my task), I should have waited 30 minutes to just open a connection!!!
I find it really ridiculous, that there is no possibility to turn off the constraint checks and open the connection for reading data, when some constraint aren't satisfied!!!
But anyway, at the end (after two days searching!) I found a solution for my work. I don't use any kind of Connection of DriverManager of this type:
Connection connection = DriverManager.getConnection(databaseURL)
Instead I use a DatabaseBuilder to open my database and get the tables and read the rows!
For anyone else, who have the same problem and just wants to connect to a MS-Access database in order to READ some data, without changing anything, I suggest this way. It is very easy and fast!
String fileName = "my_database.accdb";
File file = new File(fileName);
Database db = null;
DatabaseBuilder databaseBuilder = new DatabaseBuilder(file);
try {
db = databaseBuilder.open();
} catch(IOException e) {
e.printStackTrace();
}
Table myTable = db.getTable("myAccessTableName");
for(Row row : myTable) {
String firstName = row.getString("first_name");
String lastName = row.getString("last_name");
}
The Database, DatabaseBuilder, Row and Table are from "jackcess". So these imports are needed:
import com.healthmarketscience.jackcess.Database;
import com.healthmarketscience.jackcess.DatabaseBuilder;
import com.healthmarketscience.jackcess.Row;
import com.healthmarketscience.jackcess.Table;
More examples of using this way can be found here:
Java Code Examples
and here:
UCanAccess

MySQLSyntaxErrorException for a join command which is working fine on MySQL workbench

String query = "select Books.BookId, Books.Title, Book_Loans.BranchId, count(Book_Loans.BookLoanId) as NoOfCopies from (Book_Loans join Books"
+ "on (Book_Loans.BookId = Books.BookId)) where Books.BookId = ? group by (Book_Loans.BranchId)";
preparedStatement = connect.prepareStatement(query);
preparedStatement.setLong(1, bookId);
resultSet = preparedStatement.executeQuery();
while(resultSet.next()) {
System.out.println("BookId:"+resultSet.getLong(1)+"\nTitle:"+resultSet.getString(2)+"\nBranchId:"+resultSet.getLong(3)+"\nNoOfCopies:"+resultSet.getInt(4)+"\n");
I am trying to execute the above code snippet but I am getting MySQLSyntaxErrorException as below:
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 '(Book_Loans.BookId = Books.BookId)) where Books.BookId = 75 group by (Book_Loans' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3976)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3912)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2683)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2486)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1858)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1966)
at libraryModel.CopiesCheckedOutFromEachBranchForABook.numberOfCheckedOutCopies(CopiesCheckedOutFromEachBranchForABook.java:36)
at libraryModel.Main.main(Main.java:47)
The tables related to the queries are as below:
Books(BookId, AuthorName, Title, (Publisher)Name)
Book_Loans(BookLoanId, DateOut, DueDate, BranchId, BookId, CardNo)
I am trying to display the number of copies of books checked out from each branch by asking the user to enter the branchId. The query is working fine when I ran it on MySQL workbench but giving me syntax error on Eclipse.
You are missing a space between "books" and "on". Add it and you should be fine.
The SQL query is not correct You got to add a space between Books and on. ALso, there is no need to put additional parenthesis
Use:
String query = "select Books.BookId, Books.Title, Book_Loans.BranchId, count(Book_Loans.BookLoanId) as NoOfCopies from Book_Loans join Books on Book_Loans.BookId = Books.BookId where Books.BookId = ? group by Book_Loans.BranchId";
Your query doesn't make sense. You are saying to aggregate by the branch, and then including information about books. In most databases -- and even in the more recent versions of MySQL -- this would fail.
Your query should look more like this:
select bl.BranchId, count(*) as NumCopies
from Book_Loans bl join
Books b
on bl.BookId = b.BookId
where b.BookId = ?
group by bl.BranchId;
If you want to include information about the book, then the proper way would be to use aggregation functions or to include the columns in the group by:
select bl.BranchId, count(*) as NumCopies, b.BookId, b.Title
from Book_Loans bl join
Books b
on bl.BookId = b.BookId
where b.BookId = ?
group by bl.BranchId, b.BookId, b.Title;
Notes that table aliases make a query easier to write and read.
Of course, once you get the query correct, you need to implement it correctly in your application, including getting the spacing correct around the lines of the query.

NullPointerException while accessing HSQLDB database

I am accessing HSQLDB through A jdbc drive in my java program. The script file of the database is as follows.
CREATE SCHEMA PUBLIC AUTHORIZATION DBA
CREATE CACHED TABLE TBL1(ID CHAR(5),NAME VARCHAR(11),ZIP VARCHAR(11))
CREATE UNIQUE INDEX IDX_ID ON TBL1(ID)
CREATE CACHED TABLE TBL2(ID CHAR(5),STREET CHAR(5))
CREATE INDEX IDX_RS_ID ON TBL2(ID)
CREATE CACHED TABLE TBL3(ID VARCHAR(8) NOT NULL PRIMARY KEY,LON FLOAT,LAT FLOAT)
CREATE GLOBAL TEMPORARY MEMORY TABLE OVERLAY(ID CHAR(8),AROUTE CHAR(10),ZROUTE
CHAR(10),TYPE CHAR(8)) ON COMMIT PRESERVE ROWS
SET TABLE TBL1 INDEX'4490648 5643624 0'
SET TABLE TBL2 INDEX'529105280 529105280 0'
SET TABLE TBL3 INDEX'775814624 0'
CREATE VIEW OVERLAYSPAN (ID,STREET) AS SELECT DISTINCT ID, NAME FROM OVERLAY AS O, TBL2 as
R WHERE O.ID = R.ID
CREATE USER SA PASSWORD ""
GRANT DBA TO SA
SET WRITE_DELAY 10
In the java program, I am first removing all entries (1000 entries) from TBL1 and reinserting new entries (1500) in the same table. The program executes normally, but, when I am attempting to re-execute the same program, I am getting the following error.
java.sql.SQLException: error in script file line: 9 S1000 General error
java.lang.NullPointerException in statement [SET TABLE TBL2 INDEX'529105280 529105280 0']
Here is the fill stack trace from the program.
java.sql.SQLException: error in script file line: 9 S1000 General error java.lang.NullPointerException in statement [SET TABLE TBL2 INDEX'529105280 529105280 0']
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.jdbcConnection.<init>(Unknown Source)
at org.hsqldb.jdbcDriver.getConnection(Unknown Source)
at org.hsqldb.jdbcDriver.connect(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at HSQLTesting.main(HSQLTesting.java:98)
Where at line 98, the program is attempting to make a connection with the database.
Connection sqlconnect = DriverManager.getConnection("jdbc:hsqldb:file:C:/birdseyedb/birdseye", "SA", "");
Any idea what's going wrong here?
Thanks in advance.

Derby SQL Script Bulk Import

my goal is to import data into a derby database. The data was extracted from a MySQL instance in form of a SQL dump and I took care with a script that I only use the insert-statements and also that the escaping of the MySQL specific syntax is transformed to Derby correctly.
To Test, I use the derby-maven-plugin:
export MAVEN_OPTS=-Xmx2048m; mvn derby:run
In the first step, I create the schema in the derby instance (using DDLUtils from MySQL, this works fine).
Second, I try to import the data. I use ij on the command line with the following (shortend) script:
CONNECT 'jdbc:derby://localhost:1527/foodmart';
SET SCHEMA APP;
autocommit off;
INSERT INTO "ACCOUNT" VALUES (1000,NULL,'Assets','Asset','~',NULL), (2000,NULL,'Liabilities','Liability','~',NULL),(3000,5000,'Net Sales','Income','+',NULL),(3100,3000,'Gross Sales','Income','+','LookUpCube(\"[Sales]\",\"(Measures.[Store Sales],\"+time.currentmember.UniqueName+\",\"+ Store.currentmember.UniqueName+\")\")'),(3200,3000,'Cost of Goods Sold','Income','-',NULL),(4000,5000,'Total Expense','Expense','-',NULL),(4100,4000,'General & Administration','Expense','+',NULL),(4200,4000,'Information Systems','Expense','+',NULL),(4300,4000,'Marketing','Expense','+',NULL),(4400,4000,'Lease','Expense','+',NULL),(5000,NULL,'Net Income','Income','+',NULL);
...
commit;
As you can see, for every row of a table there is a bracket containing the sample data.
There are of course several more insert statments for other tables. After finishing some inserts correctly, the bulk importing process chokes at a really big dataset (> 1000 rows) due to following exception (from the derby-logs):
java.lang.StackOverflowError
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.TableOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.TableOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.TableOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.TableOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SetOperatorNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.UnionNode.bindExpressions(Unknown Source)
... and many lines more repeatingly because of the recursive nature...
Cleanup action completed
ij prints on the command line:
FEHLER XJ001: DERBY SQL error: SQLCODE: -1, SQLSTATE: XJ001, SQLERRMC: java.lang.StackOverflowError^T^TXJ001.U
Is this meaning, that derby is not capable using SQL-bulk-import scenarios?
Should I instead switching to an csv based import?
I assume from the stacktrace method calls that derby is not able to create the query plan.
Could it be possible, that for every 'data bracket' of an insert statement it will create internly an UNION statement, adding a big amount of overhead to each INSERT query.
So should I try to split my long INSERT-statements in many concise statements?
I don't have the time to look at the derby sources, so please help me!
I just used many Import statements and it worked.
It seems that for every data bracket of an INSERT statement Derby generates a method call on the stack, leeding for many brackets to a stackoverflow due to many recursive method calls.
However You just need to transform an INSERT statement from
Insert INTO VALUES (1,2,3), ..., (4,5,6);
To multiple statements:
Insert INTO VALUES (1,2,3);
...
Insert INTO VALUES (4,5,6);

using combined update and insert with hypersql

I was implementing upsert according to this great post: Insert, on duplicate update in PostgreSQL? and this works really fine with psql. However, I can't fire the same query into hsqldb which i use for testing.
my sql looks like this:
UPDATE account set name = ?, email = ?, type = ?, regts = ?, dao_updated = ? WHERE id = ?;
INSERT INTO account (id, name, email, type, regts, dao_created,dao_updated) SELECT ?,?,?,?,?,?,? WHERE NOT EXISTS (SELECT 1 FROM account WHERE id = ? );
I get the error message:
Caused by: java.sql.SQLSyntaxErrorException: unexpected token: INSERT
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
Is this a limitation of hsqldb or am I doing something wrong?
thanks in advance
Leon
HSQLDB supports the MERGE statement for this:
http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_merge_statement
The merge statement is generally more powerful than UPSERT and non-standard alternatives.
Alternatively, you can use CREATE PROCEDURE and define a procedure similar to the PostgreSQL example given in the linked answer.
http://hsqldb.org/doc/2.0/guide/sqlroutines-chapt.html#src_psm_conditional
You can use the GET DIAGNOSTICS statement to find out if the update succeeded.
http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_diagnostics_state
You apparently can't use several statements inside single executeUpdate() call. Please, call twice first time doing UPDATE, next time doing INSERT

Categories