Related
I have query like this
BEGIN IF NOT EXISTS (
SELECT * FROM some_table with(nolock)
WHERE col_1 = ? and col_2 = ? and col_3 = ?)
BEGIN
INSERT INTO some_table (col_1, col_2, col_3, col_4, col_5, col_6,
col_7, col_8, col_9, col_10, col_11, col_12, cdate)
VALUES
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, convert(date, GETDATE()))
END
ELSE
BEGIN
UPDATE some_table
SET col_4 = col_4 + ?,
col_5 = col_5 + ?,
col_6 = col_6 + ?,
col_7 = col_7 + ?,
col_8 = col_8 + ?,
col_9 = col_9 + ?,
col_10 = col_10 + ?,
col_11 = ?
WHERE col_1 = ? and col_2 = ? and col_3 = ?
END
END
And because of some requirements I have to keep this Query in String, what is already very painful for me. But I created PreparedStatement for this, which look like this:
PreparedStatement preparedStatemnt = conn.prepareCall(sqlQuery)) {
preparedStatemnt.setInt(1, value1);
preparedStatemnt.setString(2, value2);
preparedStatemnt.setString(3, value3);
preparedStatemnt.setInt(4, value1);
preparedStatemnt.setString(5, value2);
preparedStatemnt.setString(6, value3);
preparedStatemnt.setInt(7, value4);
preparedStatemnt.setInt(8, value5);
preparedStatemnt.setInt(9, value6);
preparedStatemnt.setInt(10, value7);
preparedStatemnt.setInt(11, value8);
preparedStatemnt.setInt(12, value9);
preparedStatemnt.setInt(13, value10);
preparedStatemnt.setInt(14, value11);
preparedStatemnt.setString(15, value12);
preparedStatemnt.setInt(16, value4);
preparedStatemnt.setInt(17, value5);
preparedStatemnt.setInt(18, value6);
preparedStatemnt.setInt(19, value7);
preparedStatemnt.setInt(20, value8);
preparedStatemnt.setInt(21, value9);
preparedStatemnt.setInt(22, value10);
preparedStatemnt.setInt(23, valye11);
preparedStatemnt.setInt(24, value1);
preparedStatemnt.setString(25, value2);
preparedStatemnt.setString(26, value3);
like you can see in here value which I have to put can be repeated and I would prefer to avoid it, but I do not know if there is any possibility.
And here is my question is there any way to create this statements in a way a String.fromat works, I mean
String.format("%1s, %1s, %1s, %1s", value1); // so the First(1) value is putted into all 4 places
I was thinking about using String.format to create them but I almost sure is not secure, is it? Or maybe someone can give me other suggestion how to deal with statement like this, it would be really helpful, cause I have many queries like this which I have to create.
Ps. I can not use stored procedures.
I'm getting the following 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 '' at line 1.
While trying to run the following code:
String sql = "INSERT INTO `tutors`.`appointments`"
+ "(`tutorID`, `tuteeName`, `tuteeEmail`, `time`, `date`)"
+ ("VALUES(?, ?, ?, ?, ?");
try {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, working.get(0).getTutorID());
ps.setString(2, tuteeName);
ps.setString(3, tuteeEmail);
ps.setDate(4, date);
ps.setTime(5, time);
ps.executeUpdate();
What is it producing the ' ' that the exception is referring to? I'm just learning to work with SQL in java, so I'm sure this is just a silly syntactical error...
You were not closing the VALUES parenthesis:
String sql = "INSERT INTO `tutors`.`appointments`"
+ " (`tutorID`, `tuteeName`, `tuteeEmail`, `time`, `date`)"
+ ("VALUES(?, ?, ?, ?, ?)");
Problem with your sql string. It should be
"INSERT INTO `tutors`.`appointments`"
+ "(`tutorID`, `tuteeName`, `tuteeEmail`, `time`, `date`)"
+ "VALUES(?, ?, ?, ?, ?)";
may be in your first '(' in third line.
String sql = "INSERT INTO `tutors`.`appointments`"
+ "(`tutorID`, `tuteeName`, `tuteeEmail`, `time`, `date`)"
+ ("VALUES(?, ?, ?, ?, ?");
it should be
String sql = "INSERT INTO `tutors`.`appointments`"
+ " (`tutorID`, `tuteeName`, `tuteeEmail`, `time`, `date`)"
+ " VALUES(?, ?, ?, ?, ?");
add some space in begining of second and third line also.
I have this Java Object which I will use to store counted elements from table:
private DCDataObj dc;
public class DCDataObj
{
private int datacenter; // Datacenters
.............
public DCDataObj()
{
}
public DCDataObj(int datacenter..........)
{
this.datacenter = datacenter;
..........
}
public int getDatacenter()
{
return datacenter;
}
public void setDatacenter(int datacenter)
{
this.datacenter = datacenter;
}
..........
}
I use this SQL query to count the components into the Oracle table:
ps = conn.prepareStatement("SELECT COUNT(1) AS CNT FROM COMPONENTSTATS CS, COMPONENTTYPE CT "
+ " WHERE CS.COMPONENTTYPEID = CT.COMPONENTTYPEID AND CT.COMPONENTTYPEID IN ( "
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ? " // 10
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ? " // 20
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ? " // 30
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) " // 40
+ " GROUP BY CT.NAME ORDER BY CT.NAME");
ps.setInt(1, 1000);
......
I get the result using this Java code:
ResultSet result = ps.executeQuery();
while (result.next())
{
dc = new DCDataObj(
result.getInt(1),
result.getInt(2),
result.getInt(3),
...........
);
}
I get this problem when I execute the query:
java.sql.SQLException: Invalid column index
Can you help me how I can solve this problem?
UPDATE
The SQL query works. I get this result:
CNT
----------------------
1
1
1 1
I suspect that the problem is into the return type. I suppose that I get the result as array. But can I somehow inset the result from the query into the Java object without using Array?
On each line, you end with a "?" but the next line starts with another "?" without a comma. Then you wind up with part of the string looking like ", ? ?," which is invalid JDBC syntax. You need commas in between all your "?" placeholders.
Try this, with commas added at the end of your lines "10", "20", and "30".
ps = conn.prepareStatement("SELECT CT.NAME AS COMPONENT_TYPE, COUNT(1) AS CNT FROM COMPONENTSTATS CS, COMPONENTTYPE CT "
+ " WHERE CS.COMPONENTTYPEID = CT.COMPONENTTYPEID AND CT.COMPONENTTYPEID IN ( "
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " // 10
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " // 20
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " // 30
+ " ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) " // 40
+ " GROUP BY CT.NAME ORDER BY CT.NAME");
EDIT
Now that I see your data, I see the problem. You cannot call getInt referencing the data, only the column header name or the 1-based column index. Also, your "COMPONENT_TYPE" is alphanumeric, please use getString instead of getInt. That also means you'll have to change your DCDataObj class to have a String for datacenter, not an int.
Try
dc = new DCDataObj(
result.getString("COMPONENT_TYPE"),
...........
);
or
dc = new DCDataObj(
result.getString(1),
...........
);
A colon in a bind variable or INTO specification was followed by an inappropriate name, perhaps a reserved word. You need to change the variable name and retry the operation. Did you try to get results from your query using pl/sql or SQL plus or your oracle terminal? Just to ensure you're executing the right query.
There is no column called "DATACENTER" fetched in the SELECT statement. It should be either COMPONENT_TYPE or CNT in result.getInt call.
I have this Java method which I will use to insert data from JSF form into Oracle:
public int saveData(int result) throws SQLException, java.text.ParseException, NoSuchAlgorithmException {
String SqlStatement = null;
if (ds == null) {
throw new SQLException();
}
Connection conn = ds.getConnection();
if (conn == null) {
throw new SQLException();
}
PreparedStatement ps = null;
/*
CREATE TABLE USERS(
USERID INTEGER NOT NULL,
GROUPID INTEGER,
SPECIALNUMBER VARCHAR2(60 ),
USERNAME VARCHAR2(50 ),
PASSWD VARCHAR2(50 ),
DATETOCHANGEPASSWD DATE,
ADDRESS VARCHAR2(60 ),
STATEREGION VARCHAR2(50 ),
COUNTRY VARCHAR2(50 ),
USERSTATUS VARCHAR2(30 ),
TELEPHONE VARCHAR2(50 ),
DATEUSERADDED DATE,
USEREXPIREDATE DATE,
DATEUSERLOCKED CHAR(20 ),
CITY VARCHAR2(50 ),
EMAIL VARCHAR2(50 ),
DESCRIPTION CLOB
)
/
*/
try {
conn.setAutoCommit(false);
boolean committed = false;
try { /* insert into Oracle the default system(Linux) time */
InsertSqlStatement = "INSERT INTO USERS"
+ " (USERID, GROUPID, SPECIALNUMBER, USERNAME, PASSWD, DATETOCHANGEPASSWD,"
+ " ADDRESS, STATEREGION, COUNTRY, USERSTATUS, TELEPHONE, DATEUSERADDED,"
+ " USEREXPIREDATE, DATEUSERLOCKED, CITY, EMAIL, DESCRIPTION)"
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
UpdateSqlStatement = "UPDATE USERS "
+ "SET "
+ "USERID = ?, "
+ "GROUPID = ?, "
+ "SPECIALNUMBER = ?, "
+ "USERNAME = ?, "
+ "PASSWD = ?, "
+ "DATETOCHANGEPASSWD = ?, "
+ "ADDRESS = ?, "
+ "STATEREGION = ?, "
+ "COUNTRY = ?, "
+ "USERSTATUS = ?, "
+ "TELEPHONE = ?, "
+ "DATEUSERADDED = ?, "
+ "USEREXPIREDATE = ?, "
+ "DATEUSERLOCKED = ?, "
+ "CITY = ?, "
+ "EMAIL = ?, "
+ "DESCRIPTION = ? "
+ "WHERE USERID = " + id;
ps = conn.prepareStatement(SqlStatement);
ps.setString(1, settingsMap.get("USERID"));
ps.setString(2, settingsMap.get("GROUPID"));
ps.setString(3, settingsMap.get("SPECIALNUMBER"));
ps.setString(4, settingsMap.get("USERNAME"));
ps.setString(5, passwdConvert(settingsMap.get("PASSWD")));
ps.setDate(6, toDate(settingsMap.get("DATETOCHANGEPASSWD")));
ps.setString(7, settingsMap.get("ADDRESS"));
ps.setString(8, settingsMap.get("STATEREGION"));
ps.setString(9, settingsMap.get("COUNTRY"));
ps.setString(10, settingsMap.get("USERSTATUS"));
ps.setString(11, settingsMap.get("TELEPHONE"));
ps.setDate(12, toDate(settingsMap.get("DATEUSERADDED")));
ps.setDate(13, toDate(settingsMap.get("USEREXPIREDATE")));
ps.setDate(14, toDate(settingsMap.get("DATEUSERLOCKED")));
ps.setString(15, settingsMap.get("CITY"));
ps.setString(16, settingsMap.get("EMAIL"));
ps.setString(17, settingsMap.get("DESCRIPTION"));
ps.executeUpdate();
conn.commit();
committed = true;
}
finally
{
if (!committed) {
conn.rollback();
}
}
} finally {
/* Release the resources */
ps.close();
conn.close();
}
return result;
}
Right now I cannot test the SQL query. Can you tell me is it valid and how I can optimize the SQL query for performance?
Right now I cannot test the SQL query. Can you tell me is it valid ...
Not with any certainty. (Why don't you wait until you CAN test it??)
... and how I can optimize the SQL query for performance?
It is not entirely clear what you are trying to do. However, here are some suggestions on performance:
You are creating and releasing a database connection for each SQL statement executed. That has to be bad for performance.
There is no need to do an insert followed by an update of the same record ... if that is what you are proposing to do.
You will get performance by doing a bulk or batch insert or update rather than inserting records one at a time.
If you are inserting lots of data into an empty table with lots of indexes, then you may get better performance if you do the insertions first and create the indexes afterwards.
At the level of a single query (i.e. the "UPDATE"), you probably cannot make the query significantly faster.
The only improvement you can make is put the id as '?' also:
UPDATE USERS "
+ "SET "
+ "USERID = ?, "
+ "GROUPID = ?, "
+ "SPECIALNUMBER = ?, "
+ "USERNAME = ?, "
+ "PASSWD = ?, "
+ "DATETOCHANGEPASSWD = ?, "
+ "ADDRESS = ?, "
+ "STATEREGION = ?, "
+ "COUNTRY = ?, "
+ "USERSTATUS = ?, "
+ "TELEPHONE = ?, "
+ "DATEUSERADDED = ?, "
+ "USEREXPIREDATE = ?, "
+ "DATEUSERLOCKED = ?, "
+ "CITY = ?, "
+ "EMAIL = ?, "
+ "DESCRIPTION = ? "
+ "WHERE USERID = ?";
And of course add a set decleration:
ps.setInt(18, id);
I think there is nothing to optimize because you are inserting to only one table. Same for update. There are no joins or grouping so there is really anything you can do about it. Maybe just one note - you could use StringBuilder for code formatting :-)
If you are going to insert several rows, then you could increase performance by reusing the database connection, as well as the prepared statement. The latter requires treating the user id as a row as well, the way ftom2 suggested. Apart from that, there is little room for performance optimizations.
I have a problem during an insert in Oracle using Java and JDBC. The error obtained is:
java.sql.SQLException: ORA-00917: missing comma
The data for the insert is taken from a form like a string and is parsed to the appropiated data type and then is saved in an object called edicio. That's all OK. Then, my intention is make an insert in the DB using the data of this object.
Here is the code of the DAO, where I'm making the insert:
public Edicio insertarCurs(Connection con, Edicio ed) throws SQLException {
PreparedStatement stm = null;
ResultSet rst = null;
// Insert
StringBuffer sql = new StringBuffer();
sql.append("INSERT INTO curs (id, nom, idarea, area, programa, datainici)");
sql.append(" VALUES (?, ?, ?, ?, ?, ?");
logger.info("Building insert works fine.");
try {
stm = con.prepareStatement(sql.toString());
// params
stm.setLong(1, ed.getIdEdicio());
stm.setString(2, ed.getNomEdicio());
stm.setLong(3, ed.getIdArea());
stm.setString(4, ed.getArea());
stm.setString(5, ed.getPrograma());
// Conversion from Java Date to SQL Date
java.sql.Date sqlDate = new java.sql.Date(ed.getDataInici().getTime());
logger.info("sqlDate before the insert is: "+ sqlDate); //0011-12-02
stm.setDate(6, sqlDate);
// Data and results commented
logger.info("Id edicio: "+ ed.getIdEdicio()); //6
logger.info("Nom edicio: "+ ed.getNomEdicio()); //test
logger.info("Id area: "+ ed.getIdArea()); //0
logger.info("Nom area: "+ ed.getArea()); //test
logger.info("Programa: "+ ed.getPrograma()); //test
logger.info("Data inici: "+ sqlDate); //2011-06-06
// We are going to execute the insert
int numRows = stm.executeUpdate();
// The program never reaches this point, fails doing the executeUpdate()
logger.info("Rows created: "+ numFiles);
...
The variable types are:
idEdicio = long
nomEdicio = String
idArea = long
area = String
programa = String
dataInici = Date
Can someone help me? Thank you in advance :)
Missing )
sql.append(" VALUES (?, ?, ?, ?, ?, ?");
should be
sql.append(" VALUES (?, ?, ?, ?, ?, ?)");
sql.append(" VALUES (?, ?, ?, ?, ?, ?)");
^--- missing parenthesis