jdbc Error, unable to connect to sql - java

i want to use database in my project, then i use this code for test( from jdbc tutorialspoint )
and change it for my code and db
then i get this error:
Creating statement...
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 'FROM test SET name=eee WHERE id=1' at line 1
Error: unable to connect to SQL!
java.sql.SQLException: 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 'FROM test SET name=eee WHERE id=1' at line 1
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2975)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1600)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1695)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3020)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2949)
at com.mysql.jdbc.Statement.execute(Statement.java:538)
at Test.main(Test.java:49)
my code:
import java.sql.*;
import java.math.*;
public class Test {
final static String DB_URL = "jdbc:mysql://localhost/testdb";
final static String USER = "root";
final static String PASS = "";
final static String JDBC_DRIVER="com.mysql.jdbc.Driver";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(DB_URL,USER,PASS);
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql = "UPDATE name FROM test SET name=eee WHERE id=1";
Boolean ret = stmt.execute(sql);
System.out.println("Return value is : " + ret.toString() );
int rows = stmt.executeUpdate(sql);
System.out.println("Rows impacted : " + rows );
sql = "SELECT id,name FROM test";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.print("ID: " + id);
System.out.print(", name: " + name);
}
rs.close();
stmt.close();
conn.close();
}
catch(ClassNotFoundException ex) {
ex.printStackTrace();
System.out.println("\n" + ex.getMessage());
System.out.println("Error: unable to load driver class!");
System.exit(1);
}
catch(IllegalAccessException ex) {
ex.printStackTrace();
System.out.println("\n" + ex.getMessage());
System.out.println("Error: access problem while loading!");
System.exit(2);
}
catch(InstantiationException ex) {
ex.printStackTrace();
System.out.println("\n" + ex.getMessage());
System.out.println("Error: unable to instantiate driver!");
System.exit(3);
}
catch (SQLException ex) {
// TODO Auto-generated catch block
ex.printStackTrace();
System.out.println("\n" + ex.getMessage());
System.out.println("Error: unable to connect to SQL!");
System.exit(4);
}
}
}
my database is:
Picture of my DB
i see this page
but it doesn't help me!

At first your statement is not valid update statement. It has convention:
update <tableName> set <column> = '<newValue>';
This is the simpliest update statement. It will update all rows. Then you can add where clause to make selection of rows. Check this out.
Secondly, you are directly adding values for columns and aren't wrapping value(s) into single quotes (they has to be wrapped otherwise it won't work). To fix it you need to add single quotes like:
set name = 'value';
Sure, this works but i don't like this approach. It's very dangerous and unsafe. I suggest you to use parametrized statements which are much more safe (beware of SQL injection) and more human-readable.
Simple example of an usage of PreparedStatement:
String sql = "UPDATE test SET name = ? WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, <nameValue>); // binding value for name column
ps.setInt(2, <idValue>); // binding value for where clause
ps.executeUpdate(); // executes statement
I would like to mention a few main advantages of PreparedStatements:
They are precompiled, database-side caching of the SQL statement leads
to overall faster execution and the ability to reuse the same SQL
statement in batches.
Automatic prevention of SQL injection attacks by built-in escaping of
quotes and other special characters.
Eases setting of non-standard Java objects in a SQL (Date, Time,
Timestamp, BigDecimal, Blob, etc.)

This Query is not correct
String sql = "UPDATE name FROM test SET name=eee WHERE id=1";
modify it to
String sql = "UPDATE test SET name='eee' WHERE id=1";

Change String sql = "UPDATE name FROM test SET name=eee WHERE id=1"; to
String sql = "UPDATE test SET name='eee' WHERE id=1";

Another good option for constructing queries is to use "Prepared statements" - take a look at the oracle tutorial - link
It helps to avoid problem with quotes like in your case and provides greater sequrity. And as I remember it provides some preparation which help to execute queries faster.

replace:
String sql = "UPDATE name FROM test SET name=eee WHERE id=1";
on
String sql = "UPDATE name FROM test SET name='eee' WHERE id=1";

Related

SQLite Query With Parameters Not Working in Java

I have a program that selects from a database given a table and column string.
public void selectAllFrom(String table, String column){
String sql = "SELECT ? FROM ?";
try (Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)){
pstmt.setString(1, column);
pstmt.setString(2, table);
ResultSet rs = pstmt.executeQuery();
while (rs.next()){
System.out.println(rs.getString(column));
}
} catch (SQLException e){
System.out.println(" select didn't work");
System.out.println(e.getMessage());
}
}
For some reason it is not working and it is going right to catch
Here is the connect() function as well:
private Connection connect(){
Connection conn = null;
// SQLite connection string
String url = "jdbc:sqlite:C:/sqlite/db/chinook.db";
try{
// creates connection to the database
conn = DriverManager.getConnection(url);
System.out.println("Connection to SQLite has been established");
} catch (SQLException e){
System.out.println(e.getMessage());
System.out.println("Connection didn't work");
}
return conn;
}
I know the problem is not with the database because I'm able to run other select queries without parameters. It is the parameters that are giving me the problem. Can anyone tell what the problem is?
A table or column name can't be used as a parameter to PreparedStatement. It must be hard coded.
String sql = "SELECT " + column + " FROM " + table;
You should reconsider the design so as to make these two constant and parameterize the column values.
? is a place holder to indicate a bind variable. When a SQL statement is executed, database first checks syntax, and validates the objects being referenced, columns and access permission for specified objects (i.e metadata about objects) and confirms that all are in place and valid. This stage is called parsing.
Post parsing, it substitutes bind variables to query and then proceeds for actual fetch of results.
Bind variables can be substituted in any place in query to replace an actual hard coded data/strings, but not the query constructs them selves. It means
You can not use bind variables for keywords of sql query (ex: SELECT, UPDATE etc.)
You can not use bind variables for objects or their attributes (i.e table names, column names, functions, procedures etc.)
You can use them only in place of a otherwise hard coded data.
ex: SELECT FIRST_NAME, LAST_NAME, 'N' IS_DELETED FROM USER_DATA WHERE COUNTRY ='CANADA' AND VERIFIED_USER='YES'
In above sample query, 'N','CANADA' and 'YES' are the only strings which can be replaced by a bind variable, not any other word.
Using bind variable is best practice of coding. It improves query performance (when used with large no. of queries in tuned database products like Oracle or MSSQL) and also protects your code against sql injection attacks.
Constructing query by concatenating strings (especially data part of query) is never recommended way. You can still construct a query by concatenation for other parts like table name or column name as long as those strings are not directly taken from input.
Below example is acceptable:
query = "Select transaction_id, transaction_date from ";
if (isHistorical(reportType)
{ query = query + "HISTORY_TRANSACTIONS" ;}
else
{query = query + "PRESENT_TRANSACTIONS" ; }
recommended practice is to use
String query_present = "SELECT transaction_id, transaction_date from PRESENT_TRANSACTIONS";
String query_historical = "SELECT transaction_id, transaction_date from HISTORY_TRANSACTIONS";
if (isHisotrical(reportType))
{
ps.executeQuery(query_historical);
}else{
ps.executeQuery(query_present);
}

Struts2: Save SQL query in the database

In my Struts2 Java web application users are allowed to query the database. As an example, the user needs to get the employee details whose first name is equal to 'Charles'. Then s/he can select the report columns and criteria (firstname='Charles').
Once the user gives above inputs it need to save the relevant SQL query into the database.
e.g. SQL -> SELECT * FROM employee WHERE firstname='Charles'
Here is what I am trying in my action class.
try {
connection = DriverManager.getConnection(
SelectAction.getDatabase(), SelectAction.getUser(),
SelectAction.getPassword());
if (connection != null) {
System.out.println("Database connection established!");
stmt = connection.createStatement();
String sql = "INSERT INTO reports (report_id, sql) values ('" + reportId + "', '" + sqlQ + "');";
System.out.println("sql--->" + sql);
// Executing query
stmt.executeQuery(sql);
return SUCCESS;
} else {
System.out.println("----Failed to make connection!");
return ERROR;
}
} catch (SQLException e) {
System.out.println("Connection Failed!!");
e.printStackTrace();
return SUCCESS;
}
This is my insert query.
INSERT INTO reports (report_id, sql) values ('mynewreport', 'SELECT * FROM employee WHERE firstname='Charles'');
I am getting following error in my console.
ERROR: syntax error at or near "Charles"
I think here I am using a String so that the problem is with quotes('). I am using postgreSQL as database.
Any suggestions to solve this issue ?
Never use string concatenation of user supplied values to build a SQL statement.
Never use string concatenation of any non-integer values to build a SQL statement.
You will leave yourself open to SQL Injection attacks and/or SQL statement errors.
Hackers will love you for allowing them to steal all your data, and the nefarious ones will corrupt or delete all your data, while laughing maniacally at you on their way to the bank.
Use PreparedStatement and parameter markers.
String sql = "INSERT INTO reports (report_id, sql) values (?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, reportId);
stmt.setString(2, sqlQ);
stmt.executeUpdate();
}

ResultSet.getNext() not working with PreparedStatement

I am trying to figure out why ResultSet.next() is never true in Java code that I am writing after I execute a SQL query that returns results from an Oracle 11g table into that ResultSet... it seems as though the code does not pick up a returned ResultSet's contents correctly when using a PreparedStatement in a java.sql.Connection. Any help appreciated, here are the details:
Table:
CREATE TABLE "SHANDB"."ABSCLOBS"
( "ID" NUMBER,
"XMLVAL" "XMLTYPE",
"IDSTRING" VARCHAR2(20 BYTE)
)
Data:
INSERT INTO absclobs VALUES ( 1,
xmltype('<?xml version="1.0"?>
<EMP>
<EMPNO>221</EMPNO>
<ENAME>John</ENAME>
</EMP>', '1'));
INSERT INTO absclobs VALUES (2,
xmltype('<?xml version="1.0"?>
<PO>
<PONO>331</PONO>
<PONAME>PO_1</PONAME>
</PO>', '2'));
Java code I am running to get values from the above to test the code:
public static void main(String[] args) throws Exception {
try {
String url = "jdbc:oracle:thin:#//localhost:1521/xe";
String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
String user = "shandb";
String password = "test";
Class.forName(driver);
connection = DriverManager.getConnection(url,user, password);
String selectID1 = "SELECT a.xmlval.getClobval() AS poXML FROM absclobs a where idstring=? and id=? ";
PreparedStatement preparedStatement = connection.prepareStatement(selectID1);
preparedStatement.setString(1, "1");
preparedStatement.setInt(2, 1);
rowsUpdated = preparedStatement.executeQuery();
while(rowsUpdated.next()){
String clobxml = rowsUpdated.getString(1);
System.out.println(clobxml);
}
} catch (ClassNotFoundException cnfe) {
System.err.println(cnfe);
} catch (SQLException sqle) {
System.err.println(sqle);
}
finally{
System.out.println("Rows affected: " + rowsUpdated);
connection.close();
}
}
This part of the above code is never run, which I don't understand:
while(rowsUpdated.next()){
String clobxml = rowsUpdated.getString(1);
System.out.println(clobxml);
}
... however the final print statement shows that the ResultSet is not empty:
Rows affected: oracle.jdbc.driver.OracleResultSetImpl#15f157b
Does anyone know why I can't display the actual retrieved XML clob contents, and/or why the while block above is never true?
Thanks :)
Your diagnostics are incorrect - this:
Rows affected: oracle.jdbc.driver.OracleResultSetImpl#15f157b
doesn't show that the result set is non-empty. It just shows that the value of rowsUpdated is a reference to an instance of oracle.jdbc.driver.OracleResultSetImpl, which doesn't override toString(). That can very easily be empty.
I suspect the problem is just that your WHERE clause doesn't match any records. For the sake of diagnostics, I suggest you change it to just:
String selectID1 = "SELECT a.xmlval.getClobval() AS poXML FROM absclobs a";
(and get rid of the parameter-setting calls, of course). That way you should be able to see all your table's values. You can then work on discovering why your WHERE clause wasn't working as expected.
(As an aside, it's not clear why you haven't declared connection or rowsUpdated in the code in the question. They should definitely be local variables...)

How to create and execute an SQL update statement

I have a table inside consist of variable like Username, ContactNo, Date, Name.
And i would like to do a update for Username and ContactNo only to the original record in the database.
How can i make use of update sql statement to do it?
Below is my SELECT sql statement.
public void dbData(String UName)
{
try
{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/assignment","root","mysql");
ps = con.createStatement();
SQL_Str="Select username,numberOfBid from customer where username like ('" + UName +"')";
//SQL_Str="Select * from customer";
rs=ps.executeQuery(SQL_Str);
rs.next();
dbusername=rs.getString("username").toString();
dbbid=rs.getInt("numberOfBid");
//UName2 = rs.getString("username").toString();
UName2 = username;
}
catch(Exception ex)
{
ex.printStackTrace();
System.out.println("Exception Occur :" + ex);
}
}
http://dev.mysql.com/doc/refman/5.0/en/update.html
And please study...
Here is a quick and dirty solution: when you have modified your values, just add something like this
String updSQL = "udate table set numberOfBid = " + dbbid + " where user = " + UName;
ps.executeUpdate(updSQL);
There are however 1000 improvements you can make such using prepared statementsand placeholders:
String updSQL = "udate table set numberOfBid = ? where username like ?";
PreparedStatement pstmt = con.prepareStatement(updSQL);
pstmt.setInt(0, dbbid);
pstmt.setString(1, UName);
pstmt.execute();
May I suggest you to have a look at Hibernate, Spring JDBC, JPA... which are on a much higher level than JDBC is.

how to execute bulk insert statement in java (using JDBC) with db=SQL Server 2008 Express

I am trying to execute a BULK INSERT statement on SQL Server 2008 Express.
(It basically takes all fields in a specified file and inserts these fields into appropriate columns in a table.)
Given below is an example of the bulk insert statement--
BULK INSERT SalesHistory FROM 'c:\SalesHistoryText.txt' WITH (FIELDTERMINATOR = ',')
Given below is the Java code I am trying to use (but its not working)...Can someone tell me what I am doing wrong here or point me to a java code sample/tutorial that uses the Bulk Insert statement? --
public void insertdata(String filename)
{
String path = System.getProperty("user.dir");
String createString = "BULK INSERT Assignors FROM " + path + "\\" +filename+ ".txt WITH (FIELDTERMINATOR = ',')";
try
{
// Load the SQLServerDriver class, build the
// connection string, and get a connection
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://arvind-pc\\sqlexpress;" +
"database=test01;" +
"user=sa;" +
"password=password1983";
Connection con = DriverManager.getConnection(connectionUrl);
System.out.println("Connected.");
// Create and execute an SQL statement that returns some data.
String SQL = "BULK INSERT dbo.Assignor FROM " + path + "\\" +filename+ ".txt WITH (FIELDTERMINATOR = ',')";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(SQL);
// Iterate through the data in the result set and display it.
while (rs.next())
{
//System.out.println(rs.getString(1) + " " + rs.getString(2));
System.out.println(" Going through data");
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
System.exit(0);
}
}
I'd guess that your SQL string is missing the single quotes around the filename. Try the following:
String SQL = "BULK INSERT dbo.Assignor FROM '" + path + "\\" +filename+ ".txt' WITH (FIELDTERMINATOR = ',')";
EDIT in response to your comment: I wouldn't expect there to be anything in the ResultSet following a bulk insert, in much the same way that I wouldn't expect anything in a ResultSet following an ordinary INSERT statement. These statements just insert the data they are given into a table, they don't return it as well.
If you're not getting any error message, then it looks like your bulk insert is working. If you query the table in SQLCMD or SQL Server Management Studio, do you see the data?
INSERT, UPDATE, DELETE and BULK INSERT statements are not queries, so you shouldn't be using them with the executeQuery() method. executeQuery() is only intended for running SELECT queries. I recommend using the executeUpdate(String) method instead. This method returns an int, which is normally the number of rows inserted/updated/deleted.

Categories