Derby Embedded database strange behaviour, SQLSyntaxErrorException - java

I've got an embedded database in a Java project with a table TOOLS_IMAGES with two columns "TOOL_id" (int) and "TOOL_image" (blob).
I try to get the blob with following code:
rs = stmt.executeQuery("SELECT * FROM 'TOOLS_IMAGES' WHERE 'TOOL_id' = " + id);
The program trys to get like 15 different images at this way one after another. When I run the program it sometimes manages to get one image, sometimes two, sometimes even six, but at one point it always throws following exception. And after that one fail, it throws this exception for every following image:
java.sql.SQLSyntaxErrorException: Syntax error: Encountered "\'TOOLS_IMAGES\'" at line 1, column 15.
Caused by: ERROR 42X01: Syntax error: Encountered "\'TOOLS_IMAGES\'" at line 1, column 15.
Why do I use apostophes in the SQL query? I already tried it without them, but here sql converts all my lowercases in the query to uppercases and complains afterwars that it can't find that column -.-
Looks like this:
rs = stmt.executeQuery("SELECT * FROM TOOLS_IMAGES WHERE TOOL_id = " + id);
and
java.sql.SQLSyntaxErrorException: Column 'TOOL_ID' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'TOOL_ID' is not a column in the target table.
Caused by: ERROR 42X04: Column 'TOOL_ID' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'TOOL_ID' is not a column in the target table.
Edit:
Here's the script, which I used to create the table
create table TOOLS_IMAGES
(
"TOOL_id" INTEGER not null
constraint TOOLS_IMAGES_PK
primary key,
"TOOL_mask" BLOB,
"TOOL_img" BLOB
);

Try to use:
ResultSet rs = stm.executeQuery("SELECT * FROM TOOLS_IMAGES WHERE \"TOOL_id\" = " + 1);
If you put:
rs = stmt.executeQuery("SELECT * FROM TOOLS_IMAGES WHERE TOOL_id = " + id);
It will be processed by Derby like :
rs = stmt.executeQuery("SELECT * FROM TOOLS_IMAGES WHERE TOOL_ID = " + id);
which are not the same
For more info visit

Related

2-parameter PreparedStatement is throwing syntax error, SQL State 42601, near second argument [duplicate]

This question already has an answer here:
Using parameter values for schema and table in Postgresql
(1 answer)
Closed 2 years ago.
I am creating a simple java application that uses a postgresql database which I have already created (the database has been created, not the application).
One of the TABLEs is called 'Employee'.
It has an attribute called 'eid', short for employee id.
I am trying to use a PreparedStatement to generalize a database SELECT query. I want there to be two parameters which are generalized. I would also like to get the length of the result, so I created a second PreparedStatement to find that.
The code seems quite simple, but I keep getting the same syntax error.
Here is the code I am trying to run:
public static String[] select(Connection conn, String arguments) {
try {
PreparedStatement preparedSelect = conn.prepareStatement("SELECT ? FROM ?");
PreparedStatement preparedCount = conn.prepareStatement("SELECT COUNT(*) FROM ?");
String[] arrOfStr = arguments.split(" ", 0);
System.out.println(arrOfStr[0].equals("eid"));
System.out.println(arrOfStr[1].equals("Employee"));
preparedSelect.setString(1, arrOfStr[0]);
preparedSelect.setString(2, arrOfStr[1]);
preparedCount.setString(1, arrOfStr[1]);
ResultSet rsSelect = preparedSelect.executeQuery();
ResultSet rsCount = preparedCount.executeQuery();
...
In the first line's argument, I would like the SELECT query to be: "SELECT eid FROM Employee".
In the second line's argument, I would like the SELECT query to be: "SELECT COUNT(*) FROM Employee".
The user who uses this application enters (earlier in the program) the "arguments" argument found in the arguments of the "select" function. The "arrOfStr" string array will contain these two strings, "eid", and "Employee".
To check that "arrOfStr" has the correct values, I printed the booleans resulting from the .equals() function comparing the values to the strings I want which, again, are "eid", and "Employee".
In the console the results are, not to my surprise:
true
true
Thus, in the next 3 lines, I set the String values "eid" and "Employee" into the PreparedStatements.
Finally, I execute the queries in the following 2 lines. Both of these query executions (I have tried switching them around) give me a very similar error. For the given code I get the error:
SQL State: 42601
ERROR: syntax error at or near "$2"
Position: 16
This is stating that there is an issue with the syntax of the string "Employee".
When I go directly to my postgresql database, and input:
SELECT eid FROM Employee;
I get the output:
1663
1983
1357
...
Could someone explain this syntax error?
As mentioned by Elliott, you cannot bind the table name that way.
To achieve your goal, try this:
String[] arrOfStr = arguments.split(" ", 0);
PreparedStatement preparedSelect = conn.prepareStatement("SELECT ? FROM " + arrOfStr[1]);
PreparedStatement preparedCount = conn.prepareStatement("SELECT COUNT(*) FROM " + arrOfStr[1]);

JDBC - NetBeans x MySQL

I'm trying to create a Java Application in NetBeans which allows the user to use most MySQL RDBMS functionalities through a GUI. I have successfully written the code for the following :
Creating a Database
Dropping a Database
Creating a Table giving options for table name, no. of columns, data type for every column
I'm stuck at the part where the user gets to insert a record in the table that was just created. I'm unable to figure out how the "insert into table values ..." query can be dynamically created and passed depending on the table the user wants to enter this record in. The table could have any number of columns, of course.
I dont know if this is the correct method, but when I faced this same problem in the past, this is how I solved it :
I ran this query to find the number of columns in the table
SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_catalog = 'database_name' AND table_name = 'table_name'
Then created a dynamic sql query based on no of columns:
String sql = "Insert into tablename values(";
for(int i = 1;i<=columns;i++){
sql += "?";
if (i < columns) {
sql += ", ";
}
}
sql+=");";
Then fired a Prepared Statement
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
If you also don't know the constraints and datatype of the columns, try parsing
desc tablename
I know this must be the shittiest workaround, but it worked for me;)

Get specific columns of table in hibernate using addEntity

I am familiar with Java but really new with ORM and Hibernate.
I am using the following query to get the resultset of all columns of a table in hibernate.
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").addEntity(Neighborhood.class).list();
I want to get only two specific column from this table. I looked up over the internet but not able to find the solution which can be used as a modification of above statement.
I tried the below query but getting - SQLGrammarException: could not extract ResultSet
(List<Neighborhood>)session.createSQLQuery("SELECT neighborhoodName,educationYouth FROM Neighborhood").addEntity(Neighborhood.class).list();
Edit:
Two more attempted queries after #scaryWombat's suggestion. Both give the same exception
First
List list = session.createSQLQuery("SELECT neighborhoodName,educationYouth FROM Neighborhood").list();
Second
String sql = "SELECT neighborhoodName,educationYouth FROM Neighborhood";
SQLQuery query = session.createSQLQuery(sql);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();
Edit2:
After #Tehmina's solution, I am getting one error - java.sql.SQLException: Column 'educationYouth' not found because educationYouth is an object of class name "EducationYouth".
In the Neighborhood table there is no column with name educationYouth but all the column from EducationYouth class.
Try this
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").list();
To avoid the overhead of using ResultSetMetadata, or simply to be more explicit in what is returned, one can use addScalar():
(List<Neighborhood>)session.createSQLQuery("SELECT * FROM Neighborhood").addScalar("neighborhoodName", Hibernate.STRING).addScalar("educationYouth", Hibernate.STRING);
Or try this
Hibernate automatically converts the data into appropriate type. The automatic conversion does not work in all cases and in that case we have an overloaded version of addScalar():
SQLQuery q = session.createSQLQuery("SELECT * FROM Neighborhood");
q.addScalar("neighborhoodName");
q.addScalar("educationYouth");
List<Object[]> rows = q.list();
for (Object[] row : rows) {
System.out.println(row[0] + " " + row[1] );
Don't forget to check in the hibernate config file
<!--hibernate.cfg.xml -->
<property name="show_sql">true</property>
I hope it would resolve your error.

SQL works from PMA but not Java

I have a prepared statement like so:
CREATE TABLE IF NOT EXISTS ? (uuid VARCHAR(128), item VARCHAR(48), value FLOAT, UNIQUE (uuid))
If I execute this directly in PMA, but replacing the ? with any text text, it works perfectly and it creates the table correctly. However, if I run it from Java it doesn't work.
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 ''Murder_PlayerData' (uuid VARCHAR(128), item VARCHAR(48), value FLOAT, UNIQUE (u' at line 1
Here's the Java code
String table = "Murder_PlayerData";
String execute = "CREATE TABLE IF NOT EXISTS ? (uuid VARCHAR(128), item VARCHAR(48), value FLOAT(11), UNIQUE (uuid))";
PreparedStatement statement = sql.getConnection().prepareStatement(execute);
statement.setString(1, table);
statement.execute();
Why does it work in PMA but not when I do it from Java?
Prepared statements can't be used to define table names, but to define values related to columns (insert values, values for where or having conditions, etcetera). One way to understand it is: Prepared Statements are for DML operations, not for DDL operations.
If you want to build a table on runtime, you need to build the SQL statement "by hand":
String table = "Murder_PlayerData"
String strSQL = "create table if not exists " + table + "("
// Add your column definitions
+ ")"
Statement stmt = conn.createStatement();
stmt.execute(strSQL);
Notice that, if the variable table can be filled with data provided by the user, your code will be vulnerable to SQL Injection Attacks. I recommend you don't create tables if their names must be provided by users, but rather create the tables without any user interaction and then insert the values, using some kind of key to identify which records belong to each user.

JDBC ResultSet::RefreshRow not working with Cascading update

I'm trying to throw together a quick JDBC app using Postgres as the DB and am running into an interesting issue.
I currently have 2 tables, table1 and table2.
CREATE TABLE table1
(
a character varying NOT NULL,
b integer NOT NULL,
CONSTRAINT table1_pkey PRIMARY KEY (b)
)
CREATE TABLE table2
(
c character varying NOT NULL,
d integer,
CONSTRAINT table2_pkey PRIMARY KEY (c),
CONSTRAINT table2_d_fkey FOREIGN KEY (d),
REFERENCES table1(b) MATCH SIMPLE
ON UPDATE CSCADE ON DELETE CASCADE
)
As the backend of my program I'm SELECTing * and holding on to the ResultSet from my query. Each table has 1 row of simple values in it, doesn't seem to matter what they are.
My statement is created with the flags ResultSet.TYPE_SCROLL_INSENSITIVE and ResultSet.CONCUR_UPDATE. Although I have tried SCROLL_SENSITIVE as well.
If I try the following (assumgin ResultSet rs/rs2 are valid and point to table1/table2 respectively:
rs.first(); // move to the first row (only row)
rs.updateInt(2, 50); // update our primary key, which is also the cascading fk
// 50 could be any number
print(rs); // Will show the old value
rs.updateRow();
print(rs); // Will show the new value
rs2.refreshRow(); // make sure we get the latest data from table2
print(rs2); // will show the old data?
I was hoping to see the new values due to the cascade. If I quit and re-run the app, not changing any input, then it will print the correct table2 values. I'm guessing this is due to re-running the SELECT statement. If I look at the table by running psql or pgadmin3, the values seem like they're changing. So it seems like refreshRow() isn't bringing down the latest stuff. Would anyone have any idea why?
I'm using:
java 1.6_29
postgresql-9.1-901.jdbc4.jar
Any help would be appreciated.
I hope you got it sorted out since it's an old question but just for the record I post here a snippet that I tried and which is working for me:
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT * FROM table1");
Statement stmt2 = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs2 = stmt2.executeQuery("SELECT * FROM table2");
rs.first(); // move to the first row (only row)
rs.updateInt(2, 50); // update our primary key, which is also the
// cascading fk 50 could be any number
System.out.println(rs.getString(2)); // Prints the old value 12
rs.updateRow();
System.out.println(rs.getString(2)); // Prints the new value 50
rs2.first();
rs2.refreshRow(); // make sure we get the latest data from table2
System.out.println(rs2.getString(2)); // Prints the new value 50

Categories

Resources