I try to insert a String into a hsqldb an it gives me this error:
> java.sql.SQLSyntaxErrorException: user lacks privilege or object not
found: S
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)
the column is set to VARCHAR(50) and the sqlstring is build like this:
String sql = "INSERT INTO Emergency Values(" + Counter.emergencyID + ","+
emergency.status +"," + "\""+ emergency.typeD +"\"" + "," + "\""+
emergency.typeB +"\"" + ","+ emergency.floorID + ")";
this ist how i execute the query:
Statement st = null;
st = con.createStatement(); // statements
int i = st.executeUpdate(sql); // run the query
PS: I know i am open to a sqlInjection like this.
EDIT: values are
sql = "INSERT INTO Emergency Values(0,1,"S","IB",1)"
If i change the string to ;
String sql = "INSERT INTO Emergency Values(" + Counter.emergencyID + ","+
emergency.status +","+ emergency.typeD +","+ emergency.typeB +","+
emergency.floorID +")";
the same error occures
Use a PreparedStatement and you won't have problems:
String sql =
"INSERT INTO Emergency (emergency_id, status, type_d, type_b, floor_id) " +
" Values (?, ?, ?, ?, ?)";
Note that I explicitly listed the column names in the insert statement. Not doing that is considered bad coding style.
I had to guess those names as you didn't show us the definition of your table. You have to replace with the correct column names of your table.
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Counter.emergencyID);
pstmt.setInt(2, emergency.status);
pstmt.setString(3, emergency.typeD);
pstmt.setInt(4, emergency.typeB);
pstmt.setInt(5, emergency.floorID);
int i = pstmt.executeUpdate(sql); // run the query
The root cause of your problem was the incorrect usage of double quotes: ". String constants have to be put in single quotes in SQL. 'foobar' is a string value. Double quotes are used for identifiers "foobar" is e.g. a column name.
Unrelated, but: the use of Counter.emergencyID lets me think that your are generating (or trying to) unique IDs in your application. Don't do that. Use a sequence or identity column in the database. Do it correctly from the beginning. For a single user application this might not make a difference, but there is no way you can implement that correctly and scalable in an application that is used by multiple users at the same time, with concurrent transactions inserting into the same table.
i found the error in #a_horse_with_no_name 's code
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, Counter.emergencyID);
pstmt.setInt(2, emergency.status);
pstmt.setString(3, emergency.typeD);
pstmt.setInt(4, emergency.typeB);
pstmt.setInt(5, emergency.floorID);
int i = pstmt.executeUpdate(sql); // run the query
note the last line, it should be
int i = pstmt.executeUpdate(); // run the query
please refer to HSQLDB cryptic exception message: "feature not supported"
I know the question is old, but I ran into the same problem and found my a solution without using PreparedStatements.
INSERT INTO TypeA (id) VALUES ("Hello");
failed (user lacks privilege or object not found: Hello ), but
INSERT INTO TYPEA (id) VALUES ('Hello');
worked. So it seems like double quotes are not accepted (see also http://www.hsqldb.org/doc/1.8/guide/ch09.html#expression-section )
Related
this is y inserting syntax
String add="INSERT INTO time_table VALUES("+coursename+"','"+coursecode+"','"+days+"','"+year+"','"+dep+"','"+time+"','"+hall+"','"+lecturer+"','"+credithours+"')";
ERROR
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 '','5','2','2','8','1','9','PA','2')' at line 1
that is what am receiving as an error.
I think correct version of your query is this :
"INSERT INTO time_table VALUES('"+coursename+"','"+coursecode+"','"+days+"','"+year+"','"+dep+"','"+time+"','"+hall+"','"+lecturer+"','"+credithours+"')";
you forgot ' in beginning of +coursename+
Don't ever use this way, it can cause Syntax error, ot SQL Injection, you have to use PreparedStatement instead for example :
String add = "INSERT INTO time_table VALUES(?, ?, ?, ?, ?,?,?,?,?)";
try (PreparedStatement insert = connection.prepareStatement(add)) {
insert.setString(1, coursename);
insert.setString(2, coursecode);
insert.setString(3, days);
insert.setString(4, year);
insert.setString(5, dep);
insert.setString(6, time);
insert.setString(7, hall);
insert.setString(8, lecturer);
insert.setString(9, credithours);
insert.executeUpdate();
}
Note if your attributes are int or float or date or ... in your table, then you have to use the correct set, for example if the year is an in you can use insert.setInt(4, year); instead.
Your real problem is in your query you miss ' here :
INSERT INTO time_table VALUES('" + coursename + "'
//----------------------------^
i need some solution from my foreign key in inserting a FK ID the problem is when i insert the ID, and the Payment it will insert first Customer_ID and the second is default to null value and on next column it will set to the inserted and the other one is null here's my code
pStmt2 = conn.prepareStatement("insert into Audittrail_tbl (Customer_ID) values ((Select Name_ID from Customer_tbl where FName ='"+txtFName.getText()+"' and LName = '"+txtLName.getText()+"'))");
pStmt2 = conn.prepareStatement("insert into Audittrail_tbl (Payment) values ('"+txtPayment.getText()+"')");
pStmt2.executeUpdate();
Your code should be:
String sql = "insert into Audittrail_tbl (Customer_ID, Payment)" +
" select Name_ID, ?" +
" from Customer_tbl" +
" where FName = ?" +
" and LName = ?";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, txtPayment.getText());
stmt.setString(2, txtFName.getText());
stmt.setString(3, txtLName.getText());
stmt.executeUpdate();
}
Or better yet, if Payment is an amount column:
// Using BigDecimal
stmt.setBigDecimal(1, new BigDecimal(txtPayment.getText()));
// Using Double
stmt.setDouble(1, Double.parseDouble(txtPayment.getText()));
Since that will parse the text to number in Java code, where you can better handle parse errors.
Note: Using insert-from-select, instead of insert-values with a subquery, will allow you to select multiple columns from Customer_tbl if needed.
You're doing two inserts, which creates two records. if you want to update the record created by the first query, you need to UPDATE for the second query instead.
And why use two queries? Why not
pStmt2 = conn.prepareStatement("
insert into Audittrail_tbl (Customer_ID, Payment)
values (
(Select Name_ID from Customer_tbl where FName ='"+txtFName.getText()+"' and LName = '"+txtLName.getText()+"'),
'"+txtPayment.getText()+"')");)");
Of course, that won't work as-is (I'm too lazy to check quote/bracket matching), but should give you the general idea.
I want to use several times the same values.
If I use in dbForge for MySQL next query,
SET #v1 = 123, #v2='2014-04-11', #v3 = 'user1', #v4='title1';
INSERT INTO test_table (TID, CREATED, OWNER, TITLE)
VALUES (#v1,#v2,#v3,#v4)
ON DUPLICATE KEY UPDATE
CREATED=#v2, OWNER=#v3, TITLE=#v4
it correctly executes, but in Java, when I use code
final String dbQuerry = "SET #v1 = %s, #v2='%s', #v3 = '%s', #v4='%s';\n"+
"INSERT INTO test_table (TID, CREATED, OWNER, TITLE)\n" +
"VALUES (#v1,#v2,#v3,#v4)\n" +
"ON DUPLICATE KEY UPDATE\n" +
"CREATED=#v2, OWNER=#v3, TITLE=#v4";
String currentQuerry = String.format(dbQuerry, t.getParam("ID"),
t.getParam("Date"),
t.getParam("User"),
t.getParam("Title"));
mDBStatement.execute(currentQuerry);
I have an exception
SQL 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 test_table (TID, CREATED, OWNER, TITLE) VALUES
(#v1,#v2,#v3,#v4) ON ' at line 2
I can use something like this
final String dbQuerry = "INSERT INTO test_table (TID, CREATED, OWNER, TITLE)\n" +
"VALUES (?,?,?,?)\n" +
"ON DUPLICATE KEY UPDATE\n" +
"CREATED=?, OWNER=?, TITLE=?";
PreparedStatement st = mDBConnection.prepareStatement(dbQuerry);
st.setInt(1, Integer.valueOf(t.getParam("ID")));
st.setString(2, t.getParam("Date"));
st.setString(5, t.getParam("Date"));
st.setString(3, t.getParam("User"));
st.setString(6, t.getParam("User"));
st.setString(4, t.getParam("Title"));
st.setString(7, t.getParam("Title"));
But it looks ugly.
Is there is a way to solve this problem?
One option is to use the special VALUES() function to reference the value that would have been inserted into a column, if the INSERT had succeeded, like this:
...
ON DUPLICATE KEY
UPDATE CREATED = VALUES(CREATED)
, OWNER = VALUES(ONWER)
, TITLE = VALUES(TITLE)
The latter form in your example is preferred, using placeholders for the bind variables. What's ugly is having to supply the same value twice.
I'd recommend something like this:
final String dbQuerry = "INSERT INTO test_table (TID,CREATED,OWNER,TITLE)\n" +
" VALUES (?,?,?, ?)\n" +
" ON DUPLICATE KEY UPDATE\n" +
" CREATED=VALUES(CREATED), OWNER=VALUES(OWNER), TITLE=VALUES(TITLE)";
PreparedStatement st = mDBConnection.prepareStatement(dbQuerry);
st.setInt(1, Integer.valueOf(t.getParam("ID")));
st.setString(2, t.getParam("Date"));
st.setString(3, t.getParam("User"));
st.setString(4, t.getParam("Title"));
And that's not ugly. That's the normative pattern.
Using the special VALUES() function is especially useful if we're upserting more than one row, either with a VALUES clause e.g.
INSERT INTO fee (fi, fo, fum)
VALUES
(1,'doo','dah'),(2,'menom','menah'),(3,'buhdeep','uhdeepee')
ON DUPLICATE KEY
UPDATE fo = VALUES(fo)
, fum = VALUES(fum)
Or, with an INSERT ... SELECT form:
INSERT INTO fee (fi, fo, fum)
SELECT t.ay, t.bee, t.cee FROM sometable t
ON DUPLICATE KEY
UPDATE fo = VALUES(fo)
, fum = VALUES(fum)
BTW... the error being returned from the first form is the type of error we'd expect if allowMultiQueries=true is not included in the connect string. Note that enabling multiple queries per execution effectively disables a security feature.
Consider carefully the SQL text that would be generated and sent to the database with some carefully crafted values:
val = "foo'; DROP TABLE students; --"
Using a prepared statement (with static SQL text with placeholder for bind variables, as in the example above) prevents this mode of SQL injection. And disallowing multiple statements in a single execution is another way to thwart SQL injection attacks.
I believe the # variables are used in stored procedures only...
Either you define a stored procedure or you can use the second option :
final String dbQuerry = "INSERT INTO test_table (TID, CREATED, OWNER, TITLE)\n" +
"VALUES (?,?,?,?)\n" +
"ON DUPLICATE KEY UPDATE\n" +
"CREATED=?, OWNER=?, TITLE=?";
PreparedStatement st = mDBConnection.prepareStatement(dbQuerry);
st.setInt(1, Integer.valueOf(t.getParam("ID")));
st.setString(2, t.getParam("Date"));
st.setString(5, t.getParam("Date"));
st.setString(3, t.getParam("User"));
st.setString(6, t.getParam("User"));
st.setString(4, t.getParam("Title"));
st.setString(7, t.getParam("Title"));
I have 3 tables, called Drivers, Offences and Points and Sofar I'm using 3 sql Strings to insert and update data in the tables
String command1 = "INSERT INTO Drivers (IDNumber, FirstName, LastName) VALUES" + drivID + FName + LName;
String command2 = "INSERT INTO Offences(IDNumber, SpeedLimit, DriverSpeed, SeatBelt, DrunkenDriving, DriversLicense) VALUES" + drivID + intspeed + intDSpeed + strSeat + strDrunk + strLicense;
String command3 = "INSERT INTO DriverPoints(IDNumber, Points) VALUES" + drivID + intpoints;
Each table is coneccted to eachother through the primary key IDNumber
Is there a way instead of having 3 Sql commands/Strings where I can have only 1 but still be able to insert and update all 3 tables?
Roughtly your query should look like this:
SELECT d.IDNumber, d.FirstName, d.LastName, o.SpeedLimit, o.DriverSpeed, o.SeatBelt, o.DrunkenDriving, o.DriversLicense, p.Points
FROM Drivers d
JOIN Offences o on (d.IDNumber = o.IDNumber)
JOIN DriverPoints p on (d.IDNumber = p.IDNumber)
WHERE (...) -- Whathever where condition you like
This will read everything.
For updating you have to perform 3 distinct updates statements or use a stored procedure or a view, but this really depends on the database you're using.
EDIT: for insert I suggest you to use PreparedStatements
String command1 = "INSERT INTO Drivers (IDNumber, FirstName, LastName) VALUES (?, ?, ?)";
PreparedStatement ps = connection.prepareStatement(command1);
ps.setInteger(1, drivID );
ps.setString(2, FName );
ps.setString(3, LName );
ps.execute();
Write a Stored Procedure.
However to make it platform independent, you should use ANSI SQL syntax.
As per BigMike's comment, you could also create a view. This will throw more light on creating a view.
You can't insert into multiple tables with one statement, so the short answer is no. You will need three statements to insert into three tables.
Also, your syntax needs to be more like:
String command1 = "INSERT INTO Drivers (IDNumber, FirstName, LastName) VALUES (" + drivID + ", " + FName + ", " + LName + ")";
Note the addition of the commas and braces.
Also, you can put all of the statements into the one query, if that is what you mean.
I have created table with 3 fields language,country,install type. When I write a query to print the maximum occuring value in each of the field, I am getting a weird problem.Can anyone say the reason.Here is my code.
PreparedStatement ps1= null;
ps1 = conn.prepareStatement("desc Configuration");
ResultSet rs1=ps1.executeQuery();
while(rs1.next()) {
System.out.print(rs1.getString(1)+":");
PreparedStatement ps2= null;
ps2 = conn.prepareStatement("select ? from Configuration c1 "+
" group by language "+
" having count(*) >= all " +
" ( select count(*) from Configuration c2 "+
" group by language )");
ps2.setString(1,rs1.getString(1));
ResultSet rs2=ps2.executeQuery();
while(rs2.next())
System.out.print(rs2.getString(1));
System.out.println();
}
The output I am getting here is language:language But the output what I am expecting is
language:english like that. I am getting later output if i replace '?' with language in the prepare statement.But if i give the same with ? I am getting what ever I have given for ps2.setString.
Why is this happening. Any solutions?
? in prepared statements is not a placeholder for textual substitution, it's a parameter, therefore its value is always interpreted as data, not as an arbitrary part of query syntax.
So, in this case the actual query being executed is an equivalent of select 'language' from ....
If you need to substitute parts of the query other than data, you have to use concatenation (beware of SQL injections!):
ps2 = conn.prepareStatement("select "
+ rs1.getString(1)
+ " from Configuration c1 group by language having count(*) >= all( select count(*)from Configuration c2 group by language )");
You can't set column names using a PreparedStatement. You can only set column values.
Instead of using this approach, you will have to build the sql yourself using concatenation, for example:
String sql = "select "+ rs1.getString(1) + " from Configuration c1 group by language having count(*) >= all( select count(*)from Configuration c2 group by language)";
The '?' mark in ps2 is recognized as literal-string. Not as a column name.