Java SQL Syntax error in INSERT INTO statement - java

I am trying to insert the data below into a table that has the columns ID[autoNumber], type[text], to[text], from[text], message[text] and attachmentLoc[text]
So the autonumber is generated I insert them supplying the column names. When it runs the console prints out:
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Syntax error in INSERT INTO statement.
at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6957)
at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7114)
at sun.jdbc.odbc.JdbcOdbc.SQLExecute(JdbcOdbc.java:3149)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.execute(JdbcOdbcPreparedStatement.java:216)
at sun.jdbc.odbc.JdbcOdbcPreparedStatement.executeUpdate(JdbcOdbcPreparedStatement.java:138)
at MultiEchoServer.saveMessage(MultiEchoServer.java:147)
at ClientHandler.run(MultiEchoServer.java:409)
The code that is bringing the error is :
try
{
String sql = "INSERT INTO Messages (type, to, from, message, attachmentLoc) VALUES(?,?,?,?,?)";
PreparedStatement stmt = database.prepareStatement(sql);
stmt.setString(1, message.getType());
stmt.setString(2, message.getTo());
stmt.setString(3, message.getFrom());
stmt.setString(4, message.getMessage());
stmt.setString(5, attachmentLoc);
stmt.executeUpdate();
}
catch (SQLException e)
{
System.out.println("Could not perform statement");
e.printStackTrace();
}
Thanks for your help

You don't state what database engine you're using, but a number of the column names (as well as the table name) are likely candidates for reserved words. The very most obvious is from.
You will need to write those identifiers in identifier quotes which are generally either the backtick character (`) or the characters [ and ] (depending on engine):
INSERT INTO `Messages` (`type`, `to`, `from`, `message`, `attachmentLoc`)
VALUES (?,?,?,?,?);
or
INSERT INTO [Messages] ([type], [to], [from], [message], [attachmentLoc])
VALUES (?,?,?,?,?);
The quoting is only required around the identifiers that are reserved words but using it around all identifiers will not hurt. Also, no reason not to include the space after VALUES and the semi-colon at the end of the statement (although most engines don't need either).

You need valid syntax for the INSERT statement. SQL does not understand the question mark.
Perhaps, you want one of the following:
'?'
NULL
''
Or some other value.
So, assuming the columns accept NULL values, you could use:
VALUES(NULL, NULL, NULL, NULL, NULL)

From is a reserved word, after this was changed to messageFrom it allowed the insertion to the database.

Related

Java prepairedStatement setInt is adding quotes in the SQL

I have a simple SQL statement that I want to execute via
String tokenInsQ = "INSERT INTO pitweb.tokens (token_user_id,token_token,token_valid,token_refresh) (?,?,?,?)";
try {
PreparedStatement p = SQL.dbConnection.prepareStatement(tokenInsQ);
p.setInt(1, r.getInt("user_id").intValue());
p.setString(2, token.getString("token"));
p.setTimestamp(3, (Timestamp)token.get("valid"));
p.setTimestamp(4, (Timestamp)token.get("renew"));
System.out.println(p);
p.executeUpdate();
p.close();
}
I expect this to work just fine. Token is a long string and r.getInt("user_id").intValue() Returns 11. The error I keep getting is
org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
Position: 82
So I added the print statement to see the SQL that it is trying to execute. The program Prints.
INSERT INTO pitweb.tokens (token_user_id,token_token,token_valid,token_refresh) ('11','really long string ','2020-03-17 13:15:22.847000 -05:00','2020-03-14 13:15:22.847000 -05:00')
I assume that my problem is that the token_user_id ('11') is in quotes. Is this because of the way that I created the Prepared Statement? or do I have a different problem. the output seems vague to me
Here is what the token table looks like
CREATE TABLE pittweb.token
(
token_id integer NOT NULL DEFAULT nextval('pittweb.token_token_id_seq'::regclass),
toekn_user_id integer,
token_valid timestamp without time zone,
toekn_refresh timestamp without time zone,
token_token text COLLATE pg_catalog."default",
CONSTRAINT token_pkey PRIMARY KEY (token_id),
CONSTRAINT token_toekn_user_id_fkey FOREIGN KEY (toekn_user_id)
REFERENCES pittweb."user" (user_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
WITH (
OIDS = FALSE
)
There is a typo in toekn_refresh as well along with toekn_user_id.
There is a typo in the column name toekn_user_id. In the insert statement, you have used token_user_id and in the DDL it is toekn_user_id

Insert data to sql using java issue

I'm facing an issue with insertion to SQL database from java code.
I'm using INSERT sql query using the java code to enter the data from XML file to SQL database.
You may suppose column named "Description".
Imagine there is a record in XML which contains apostrophe ('). The program crashes due to the error caused by the apostrophe which is included in the data.
I know that manually we can add another apostrophe and make it work, but imagine data of 10.000 records, how can we handle this issue?
Don't do this (string concatenation):
String sql = "insert into MyTable (description) values ('" + value + "')";
Statement st = connection.createStatement();
st.executeUpdate(sql);
Do do this (prepared statement):
PreparedStatement ps = connection.prepareStatement(
"insert into MyTable (description) values (?)"
);
ps.setString(1, value);
pt.executeUpdate();
The value will get correctly escaped for you. Not only does this protect against mishaps like the one you mentioned, it also helps defend you from SQL injection attacks.
Humorous illustration:
Source
You have two options, you should use PreparedStatement and bind your parameter(s). Or, if you really, really, want - you could use StringEscapeUtils.escapeSql(str).

How can I insert an XML document in PostgreSQL in Java?

I have a table in Postgresql
DROP TABLE xml_docs;
CREATE TABLE xml_docs(
id serial PRIMARY KEY,
cad_number character(50),
gkuzu_name character(50),
gkuzu xml,
rreq_name character(50),
rreq xml
)
I use JDBC for data base connection. And i want to insert whole xml document in table.
How can i make this?
UPDATE
Okey. i try
String sql = "INSERT INTO xml_docs(cad_number,gkuzu_name,gkuzu,rreq_name,rreq) VALUES(?,?,?,?,?)";
PreparedStatement stmt = ce.prepareStatement(sql);
stmt.setString(1, "11:33:5464563");
stmt.setString(2, xml_gkuzu.getName());
stmt.setString(3, xml_gkuzu.toString());
stmt.setString(4, xml_rreq.getName());
stmt.setString(5, xml_rreq.toString());
stmt.executeQuery();
ce.close();
se.close();
and get exeption
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: column "gkuzu" is of type xml but expression is of type character varying
Подсказка: You will need to rewrite or cast the expression.
Whats wrong?
UPDATE 2
When i try do this
String sql1 = "INSERT INTO xml_docs(cad_number,gkuzu_name,gkuzu,rreq_name,rreq) VALUES(11335464563,"+xml_gkuzu.getName()+",XMLPARSE("+xml_gkuzu.toString()+"),"+xml_rreq.getName()+",XMLPARSE("+xml_rreq.toString()+"))";
i get exeption
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: syntax error at or near "bf48e000b0"
I'm not sure, but try this:
First convert your XML to a Java String.
Then create an insert statement und use the XMLPARSE method of PostgreSQL to convert your value to the xml type of PostgreSQL:
INSERT INTO xml_docs(id, gkuzu) VALUES (1, XMLPARSE('<foo><bar>Hello</bar></foo>'));
See: http://wiki.postgresql.org/wiki/XML_Support
UPDATE:
Java code example:
String sql = "INSERT INTO xml_docs(id, gkuzu) VALUES (?, XMLPARSE(?))";
[...]
stmt.setString(2, "<foo>Hello World!</foo>");
This should create this statement:
INSERT INTO xml_docs(id, gkuzu) VALUES (1, XMLPARSE('<foo>Hello World!</foo>'));
Instead of rewriting the insert statement using PostgreSQL-proprietary syntax, you could use JDBC 4 SQLXML:
String xml = xml_gkuzu.toString();
SQLXML sqlxml = connection.createSQLXML();
sqlxml.setString(xml);
stmt.setSQLXML(3, sqlxml);
Though postgres has native XML Data type, from java end, You can handle with Plain strings.
You can convert your xml document to String and insert, It should work.
UPDATE:
After looking at your error, You need to pass an additional variable to the server through driver URL.
jdbc:postgresql://localhost/test?stringtype=unspecified
or
jdbc:postgresql://localhost/test?user=user&password=pass&stringtype=unspecified
The extra param stringtype=unspecified will remove the type check for the input strings.
An update to the accepted answer if you do not have Postgres built with libxml support:
Java code example:
String sql = "INSERT INTO xml_docs(id, gkuzu) VALUES (?, XML(?))";
[...]
stmt.setString(2, "<foo>Hello World!</foo>");
This should create this statement:
INSERT INTO xml_docs(id, gkuzu) VALUES (1, XML('<foo>Hello World!</foo>'));
Thus for version 9.0 and greater you may want to switch XMLPARSE ==> XML. Otherwise you will need special support for XMLPARSE
From Postgres Documentation:
The function-like expressions xmlparse and xmlserialize for converting to and from type xml are not repeated here. Use of most of these functions requires the installation to have been built with configure --with-libxml.

java.sql.SQLException: Column count doesn't match value count at row 1 Servlets Error or Mysql Error? [duplicate]

This question already has answers here:
java.sql.SQLException: Column count doesn't match value count at row 1
(3 answers)
Closed 6 years ago.
try {
Statement stmt = con.createStatement();
stmt.executeUpdate("INSERT into emailacc(fname,lname,uname,mail,passwd,passwd2,date,month,year) values('"+fname+","+lname+","+uname+","+mail+","+passwd+","+passwd2+","+date+","+selectMonth+","+year+"')");
out.println("<h3><font color='green'>Information Added Successfully.</font><br> You Are a registered User now.</h3><br>");
con.close();
} catch(Exception e) {
out.println("Exception caught : "+e);
}
Why is it happening?
Last time I did the same but it didn't happen, whats wrong with it?
Well to start with what's wrong with it is that you're including the values directly into your SQL. Don't do that. Ever. Use a parameterized SQL statement via PreparedStatement, and set the parameter values appropriately. That way you don't need to worry about SQL injection attacks, and it'll also be a lot easier to look at what the actual SQL is, without worrying about where the values come from (or rather, separating those two concerns).
I suspect the immediate problem is that you're not quoting any values, so you've got a SQL statement like a longer version of:
INSERT into Foo(name) VALUES (jon)
rather than
INSERT into Foo(name) VALUES ('jon')
... but using parameterized SQL will fix this anyway, so please don't just change the SQL to include single quotes everywhere.
Is because you are omitting single quotes, for avoid this mistakes my recommendation is to use PreraredStatement, also in order to proper close connection it mus be in a finally block , you code must look at this:
try {
PreparedStatement stmt = con.prepareStatement("INSERT into emailacc(fname,lname,uname,mail,passwd,passwd2,date,month,year) values(?,?,?,?,?,?,?,?,?)");
stmt.setString(1,fname);
stmt.setString(2,lname);
stmt.setString(3,uname);
stmt.setString(4,mail);
stmt.setString(5,passwd);
stmt.setString(6,passwd2);
stmt.setDate(7,date); //you need convert your date to java.sql.Date if 'date' field of database is of type date. If not setString is fine
stmt.setInt(8,selectMonth);
stmt.setInt(9,year);
stmt.executeUpdate();
out.println("<h3><font color='green'>Information Added Successfully.</font><br> You Are a registered User now.</h3><br>");
} catch (Exception e) {
con.rollback();
out.println("Exception caught : " + e);
} finally {
if (con != null) {
try {
con.close();
} catch(SQLException ex){
//DO NOTHING
}
}
}
You can learn more of PreparedStatemt in:
http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html
A final note: PreparedStament are more efficent thant Statement and avoid the SQL Injection hack so PrepararedStatement is more secure. Try use always a PreparedStatement
Your insert statement is missing quotes between the string insert statement should be:
INSERT into emailacc(fname,lname,uname,mail,passwd,passwd2,date,month,year) values('"+fname+"','"+lname+"','"+uname+"','"+mail+"','"+passwd+"','"+passwd2+"',"+date+","+selectMonth+","+year+")");
every column varchar or text should be between single quotes also double check your date format you might have to use the to_date function : to_date(,'DD-MM-YYYY') just a sample

Java PreparedStatement complaining about SQL syntax on execute()

This is driving me nuts... What am I doing wrong here?
ArrayList<String> toAdd = new ArrayList<String>();
toAdd.add("password");
try{
PreparedStatement pStmt = conn.prepareStatement("ALTER TABLE testTable ADD ? varchar(100)");
for (String s : toAdd) {
pStmt.setString(1, s);
pStmt.execute();
}
} catch (SQLException e) {
e.printStackTrace();
}
Results in...
02:59:12,885 ERROR [STDERR] 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 ''password' varchar(100)' at line 1
but...
ArrayList<String> toAdd = new ArrayList<String>();
toAdd.add("password");
try{
Statement stmt = conn.prepareStatement();
for (String s : toAdd) {
stmt.execute("ALTER TABLE testTable ADD "+s+" varchar(100)");
}
} catch (SQLException e) {
e.printStackTrace();
}
works perfectly... So does directly entering the text directly into the MySQL command line client.
mysql> alter table testTable add stringGoesHere varchar(100);
Query OK, 1 row affected (0.23 sec)
Records: 1 Duplicates: 0 Warnings: 0
What am I doing wrong?
The MySQL manual clearly says that ? (parameter markers) are for binding data values only, not for column names.
Parameter markers can be used only
where data values should appear, not
for SQL keywords, identifiers, and so
forth.
So you will have to use your second approach.
Placeholders in JDBC are for data, not for table, column, view or function names. And for good reason. The DB schema of an application is static most of the time and only changes rarely. There are no benefits making them dynamic.
Prepared statements need to define a fixed structure so they can be precompiled. That means you can have variable values, but never variable table names, column names, function names etc.
When using a prepared statement, your parameter is treated similarily to a string literal. As a result, your statement is equivalent to "ALTER TABLE testTable ADD \'"+s+"\' varchar(100)". Notice the single quotations around the field name in the error message.
I would suggest building a literal statement in this case, and not attempting to used a prepared statement.
You cannot submit an ALTER TABLE statement using parameters like this.
I guess it is not permissible to execute DDL statements in Java PreparedStatement.
Try using the following
pStmt.executeUpdate();
pStmt.close();

Categories

Resources