This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 4 years ago.
I just started to work with MySQL in Java, I am trying to update existing data in my database. The main purpose is to create a counter, there will update an int in the database when an action has been done.
In this case, I am trying to update the daily_search_count by increasing the integer when the code is compiling. Below you can see a picture of my DB data:
data within the database
The code I have written is intended to increase the "daily_search_count" by 1 each time the code is running. But unfortunately I get the following error:
Exception in thread "main" java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''accounts' set 'daily_search_count' = '4' where 'id' = '1'' at line 1
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:118)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:960)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1116)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1066)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1396)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1051)
at Database.main(Database.java:29)
I can't see what is wrong with my code as you can see below:
import java.sql.*;
public class Database {
public static void main(String[] args) throws Exception {
String host = "jdbc:mysql://localhost:3306/presearch";
String username = "root";
String password = "";
String query = "select * from accounts";
Connection con = DriverManager.getConnection(host, username, password);
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(query);
String userData = "";
while (rs.next()) {
if (rs.getInt(4) < 33) {
userData = rs.getInt(1) + " : " + rs.getString(2) + " daily search count : " + rs.getInt(4);
System.out.println(userData);
int counter = rs.getInt(4) + 1;
PreparedStatement updatexdd = con.prepareStatement("update 'accounts' set 'daily_search_count' = '" + counter + "' where 'id' = '" + rs.getInt(1) + "'");
int updatexdd_done = updatexdd.executeUpdate();
}
}
st.close();
con.close();
}
}
I hope someone can see what I am doing wrong.
Thanks in advance!
You have some problems in your code you have to avoid :
name of table and columns should not be between two quotes 'accounts'
make sure to use placeholder(?) to specify your attribute in the query with PreparedStatement
make sure to close the connection and statement in finally block instead
I note also that all you need is just one query
Your code should look like this :
public static void main(String[] args) throws Exception {
String host = "jdbc:mysql://localhost:3306/presearch";
String username = "root";
String password = "";
String query = "update accounts set daily_search_count = daily_search_count + 1 where daily_search_count < 33";
try (Connection con = DriverManager.getConnection(host, username, password);
PreparedStatement updatexdd = con.prepareStatement(query)) {
int updatexdd_done = updatexdd.executeUpdate();
}
}
In my code I use The try-with-resources Statement which support AutoCloseable and Closeable Interface which mean you don't need to close the connection or the statement.
Related
This question already has answers here:
How to use a tablename variable for a java prepared statement insert [duplicate]
(4 answers)
Closed 7 years ago.
This is my method:
#Override
public void deleteOneRecord(String tableName, String id) throws ClassNotFoundException, SQLException{
// Validate the parameters here.
// String sql = "DELETE FROM " + tableName + " WHERE " + column + "=" + value;
String pKeyColumnName = "";
// Statement stmt = conn.createStatement();
DatabaseMetaData dmd = conn.getMetaData();
ResultSet rs = dmd.getPrimaryKeys(null, null, tableName);
while(rs.next()){
pKeyColumnName = rs.getString("COLUMN_NAME");
System.out.println("PK column name is " + pKeyColumnName);
}
//String sql = "delete from " + tableName + " where " + pKeyColumnName + "=" + id;
String sql2 = "delete from ? where ?=?";
PreparedStatement pstmt = conn.prepareStatement(sql2);
pstmt.setString(1, tableName);
pstmt.setString(2, pKeyColumnName);
pstmt.setInt(3, Integer.parseInt(id));
pstmt.executeUpdate();
}
This is my test main:
public static void main(String[] args) throws ClassNotFoundException, SQLException {
DBStrategy db = new MySqlDBStrategy();
db.openConnection("com.mysql.jdbc.Driver", "jdbc:mysql://localhost:3306/book", "root", "admin");
System.out.println(db.findAllRecords("author", 0).toString());
db.deleteOneRecord("author", "2");
System.out.println(db.findAllRecords("author", 0).toString());
db.closeConnection();
}
The db object works, open connection works, my find all records method works,
then my deleteOneRecord blows up. I get this error:
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 ''author' where 'author_id'=2' at line 1
Now my syntax hasn't changed, I was running this code as just a Statement no problem a few minutes ago, so I must be using PreparedStatement incorrectly somehow.
Any help would be appreciated greatly.
I don't believe you can use parameters for the table name or the column name. You'll have to concatenate those into the string. Depending on where they come from, be careful about SQL injection vulnerabilities!
I am doing practice for JDBC and using NetBeans 8.1. I created a table in MS Access and wrote a program. But the problem is that when I pass column index then my program runs successfully. But I pass column name as in my table in MS Access then there occurs an error that
Column not found
I am pasting code of my program and try to explain my problem further.
package database;
import java.sql.*;
public class Database {
public static void main(String[] args) {
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:personDSN";
Connection con = DriverManager.getConnection(url);
Statement st = con.createStatement();
String sql = "SELECT *FROM students";
ResultSet rs = st.executeQuery(sql);
while(rs.next())
{
String Name = rs.getString(2);
String add = rs.getString(3);
String pNum = rs.getString(4);
System.out.println(Name + " " + add + " " + pNum);
}
con.close();
}
catch(ClassNotFoundException | SQLException sqlEx)
{
System.out.println(sqlEx);
}
}
}
As you can see in while loop that i have passed column index in getString() function. In this case my program runs successfully. But when i pass name of field/attribute which is in my database table, then it gives me error that "Column not found". For example if I pass getString("name") then it gives me above error.
Please help me to solve my problem.
Note: I have checked again and again that there is no spelling mistake in my parameter opposite to actual table in ms access.
Hey I'm making a little webapp and have a java file in it with a function what connects a db and fetches the data.
But I'm getting a exception anyone knows why because my query is valid if I'm right.
I use eclipse and mysql workbench.
Function:
import java.sql.*;
public class Functions {
public void dbConn(String nVal, String inpVal){
System.out.println("Running function...");
if(nVal != null || inpVal != null){
String sqlSerch;
if(nVal.equals("name")){
sqlSerch = "ID, aNaam FROM profiles WHERE naam = 'casper'";
}else{
sqlSerch = "naam, aNaam FROM profiles WHERE ID = " + inpVal;
}
//driver / db path
final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
final String DB_URL = "jdbc:mysql://localhost:3306/profile";
//DB user&password
final String USER = "root";
final String PASS = "";
//declare con & sql var
Connection conn = null;
Statement stmt = null;
//register jdbc driver
try{
Class.forName(JDBC_DRIVER);
//make a connection
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//SQL Statement
stmt = conn.createStatement();
String sql = "SELECT "+ sqlSerch;
ResultSet rs = stmt.executeQuery(sql);
//Declareer variablen met data uit db
//int id = rs.getInt("ID");
String naam = rs.getString("naam");
String aNaam = rs.getString("aNaam");
System.out.println( naam + aNaam);
rs.close();
stmt.close();
conn.close();
}catch(Exception e){
System.out.println(e);
}
System.out.println(" - " + nVal + " - " + inpVal);
}
}
}
exception:
java.sql.SQLException: Column 'naam' not found.
database structure:
Thank you in advance,
Casper
When you receive "name" through the nVal parameter, you select only ID and aNaam columns.
So, if you try to get values for naam from that ResultSet you get the Exception.
Also, I suggest limiting the results of your query to 1, since you use the WHERE clause with naam and ID, which seem to be not unique, unless there's some constraint not included in the screenshot.
Hope this helped.
You branch and create your queries:
if(nVal.equals("name")){
sqlSerch = "ID, aNaam FROM profiles WHERE naam = 'casper'";
}else{
sqlSerch = "naam, aNaam FROM profiles WHERE ID = " + inpVal;
}
Then regardless of the branch, you get your result set values:
String naam = rs.getString("naam");
String aNaam = rs.getString("aNaam");
But "naam" will not be in your "ID, aNaam" search.
In general, a good rule of thumb is to always return the same columns.
I am trying to get the autogenerated key from my SQL Insert preparedstatement from an oracle database. I have tried mimicking every example I could find and I always get a SQLException from the .executeUpdate() call. I am certain this works fine without the second argument in the prepareStatement() call so it is not the SQL itself. Please what am I doing wrong?
I am getting the error:
I seem to be getting this: [1/19/15 0:50:50:462 EST] 00000054
ConnectionEve A J2CA0056I: The Connection Manager received a fatal
connection error from the Resource Adapter for resource[extracted]. The
exception which was received is
com.ibm.websphere.ce.cm.StaleConnectionException: Protocol
violation:java.sql.SQLException: Protocol violation
the code goes like this
Connection conSOX = AggIOTraceUtil.getJNDISOXConnection(JNDIConn);
PreparedStatement preparedStatement = null;
String sii_agg_id = null;
if (conSOX != null)
{
preparedStatement = conSOX.prepareStatement(SII_SOX_APP_QUERY, new String[] { "SII_TASK_AGG_STATUS_ID" });
preparedStatement.setObject(1, traceObject.getTaskName());
preparedStatement.setObject(2, traceObject.getTaskType());
preparedStatement.setObject(3, traceObject.getSpTaskStartedDate());
ETC ETC ...
preparedStatement.executeUpdate();
// Get the auto generated aggregation ID
ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
if (null != generatedKeys && generatedKeys.next()) {
log.error("Hello");
sii_agg_id = generatedKeys.getString(1);
log.error("SII AGG ID = " + sii_agg_id);
My SQL query is:
private static final String SII_SOX_APP_QUERY = "insert into
SII_TASK_AGG_STATUS(SII_TASK_AGG_STATUS_ID, DATA_AGG_TASK_NAME,
"+ "TASK_TYPE, TASK_STARTED_DATE, TASK_COMPLETED_DATE, TASK_LAUNCHED_DATE,
APP_SCANNED, "+ "EXTRA_ENTITLEMENT_CHANGES, IDENTITIES_UPDATED,
LINKS_OR_GROUPS_DELETED, GROUPS_UPDATED, " + "IDENTITIES_CREATED,
GROUPS_CREATED, TASK_MESSAGE, COLUMN_NAMES, DELIMITER, LINE_SKIPPED,
"+ "LOGICAL_APP_NAME, IS_PRIMARY_TIER, AGG_STATUS, DATA_AGG_AUDIT_ID,
SII_TASK_STATUS_ID" + ")
values(SII_TASK_AGG_STATUS_SEQ.NEXTVAL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?)";
i have 2 PostgreSQL databases on different port: DB1 on port 5432 and DB2 on port 5431
and i have code to get data from DB1 like this :
try {
Class.forName("org.postgresql.Driver");
String conString = "jdbc:postgresql://127.0.0.1:5432/DB1?user=MyUser&pass=MyPass" ;
c = DriverManager.getConnection(conString);
st = c.createStatement();
ResultSet rs = st.executeQuery(query);
while (rs.next()){
vaArrL.add(rs.getDouble("va"));
vbArrL.add(rs.getDouble("vb"));
vcArrL.add(rs.getDouble("vc"));
}
and work good when i send singe query to DB1 only.
but now, i have query to both databases together like :
select va, vb from DB1.public.t1 where datatime >= 1417384860 and datatime <= 1417381199
union
select va, vb from dblink('hostaddr=127.0.0.1 port=5431 dbname=DB2 user=MyUser password =MyPass '::text,
'select va, vb
from Db2.public.t2 order by datatime ')
datos(va integer,vb integer);
when i run query from pgAdmin i get result
but when i sent query to gunction i get : connection not available
Now. How can i send my query to function and i get values?
Can you try using JDBC's setCatalog method?
setCatalog's javadoc states that:
Calling setCatalog has no effect on previously created or prepared
Statement objects. It is implementation defined whether a DBMS prepare
operation takes place immediately when the Connection method
prepareStatement or prepareCall is invoked. For maximum portability,
setCatalog should be called before a Statement is created or prepared.
try {
Class.forName("org.postgresql.Driver");
// Connect to DB1 (specified in connection string/URL).
String conString = "jdbc:postgresql://127.0.0.1:5432/DB1?user=MyUser&pass=MyPass" ;
c = DriverManager.getConnection(conString);
st = c.createStatement();
// Execute query on DB1.
ResultSet rs = st.executeQuery(query);
while (rs.next()){
vaArrL.add(rs.getDouble("va"));
vbArrL.add(rs.getDouble("vb"));
vcArrL.add(rs.getDouble("vc"));
}
// Switch to DB2 and execute query.
c.setCatalog("DB2");
Statement st2 = c.createStatement();
ResultSet rs2 = st2.executeQuery(...);
}
If the JDBC driver doesn't support setCatalog, then you can execute the SQL query USE DB2 explicitly but this might affect already open statements (I'm not sure about this).
Edit: OP wants all results from both databases in the same ResultSet.
Assuming that DB1 and DB2 are on same server, I'd recommend creating a view in database DB1 which can access tables in database DB2 and return combined results. Then you can just SELECT * from the view via JDBC and get the results.
You can use a query like this for your view (assuming that the view is created in DB1):
SELECT all.va, all.vb FROM
(SELECT va, vb, datatime FROM t2
UNION
SELECT va, vb, datatime FROM DB2.public.t2) all
ORDER BY all.datatime
Note: To access a table in another database, you need to specify [db-name].[schema].[tablename].
If your query needs dynamic arguments, then you can create a stored procedure instead of a view.
i am find 1 solution
i am use 2 connection and send to query from client to xmlrpc server, here :
String conString = "jdbc:postgresql://" + host + ":" + port + "/" + DBName +
"?user=" + user + "&pass=" + pass;
String conString1 = "jdbc:postgresql://" + host + ":" + port2 + "/" + DBName2 +
"?user=" + user + "&pass=" + pass;
c = DriverManager.getConnection(conString);
c2 = DriverManager.getConnection(conString1);
st = c.createStatement();
st2 = c2.createStatement();
List<ResultSet> resultSets = new ArrayList<>();
resultSets.add(st.executeQuery(query));
resultSets.add(st2.executeQuery(query2));
ResultSets rs = new ResultSets(resultSets);
while (rs.next()){
unbArrL.add(rs.getUnbalance("unbalance"));
}
and resultSets class to get values from DB is :
class ResultSets {
private java.util.List<java.sql.ResultSet> resultSets;
private java.sql.ResultSet current;
public ResultSets(java.util.List<java.sql.ResultSet> resultSets) {
this.resultSets = new java.util.ArrayList<>(resultSets);
current = resultSets.remove(0);
}
public boolean next() throws SQLException {
if (current.next()) {
return true;
}else if (!resultSets.isEmpty()) {
current = resultSets.remove(0);
return next();
}
return false;
}
public Double getUnbalance(String unbalance) throws SQLException{
return current.getDouble("unbalance");
}
}