Retrieve a range of records from SQL query Oracle - java

I have this Java code which is used for JSF pagination:
public List<ActiveSessionObj> list(int firstRow, int rowCount, String sortField, boolean sortAscending) throws Exception {
String SQL_LIST_BY_ORDER_AND_LIMIT = "SELECT * FROM ACTIVESESSIONSLOG ORDER BY ? ? LIMIT ?, ?";
if (ds == null) {
throw new SQLException();
}
String sortDirection = sortAscending ? "ASC" : "DESC";
String sql = String.format(SQL_LIST_BY_ORDER_AND_LIMIT, sortField, sortDirection);
Connection conn = ds.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
List<ActiveSessionObj> dataList = new ArrayList<ActiveSessionObj>();
try {
conn.setAutoCommit(false);
boolean committed = false;
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setString(1, sortField);
preparedStatement.setString(2, sortDirection);
preparedStatement.setInt(3, firstRow);
preparedStatement.setInt(4, rowCount);
resultSet = preparedStatement.executeQuery();
/* take the result from the SQL query and insert it into Array List collection */
dataList = ActiveSessionsArrayList(resultSet);
} catch (SQLException e) {
throw new Exception(e);
} finally {
conn.close();
}
return dataList;
}
I use this SQL statement to generate ArrayList:
SELECT * FROM ACTIVESESSIONSLOG ORDER BY ? ? LIMIT ?, ?
Can this SQL query be used for Oracle? Or this is MySQL specific?
Best wishes

Case1: If you want first `twenty Records` only then
select * from (
select rn,a.*
from Activesessionlogs a
order by ??)
where rn <=20
order by rn
Case2:If you want the record between `5 to 10` then
select * from (
select rownum rn,e.* from Activesessionlogs e order by ??)
where rn >=5 and rn<=10
order by rn
Eg:
Lets find an example below
select * from (
select rownum rn,e.* from emp e order by hiredate)
where rn >=5 and rn<=10
order by rn asc
Note :Rownum> or rownum>= will not work in the same query .A very good blog explaining this Oracle Rownum

LIMIT is MySQL specific. However in Oracle you can use rownum like this:
SELECT *
FROM (SELECT columnA, columnB, rownum as my_rownum
FROM ACTIVESESSIONSLOG
ORDER BY ? ?)
WHERE my_rownum <= ?
AND my_rownum >= ?

Unfortunately LIMIT is not a valid statement in oracle, it is used in MySql. However oracle has a variable ROWNUM which you can use to limit the number of rows returned:
select * from mytable where rownum <= 100 and rownum > 50
returns the second 50 records from your query.

Related

Get the inserted id of the record before or after execute the insert statement in sql

I have this method in my DAO class to insert record to a table called idea this is my method:
public long addIdea(AddIdeaDto addIdeaDto, int userId) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = getConnection();
preparedStatement = connection.prepareStatement(
"INSERT INTO IDEA ( IDEA.I_ID,IDEA.I_NO,IDEA.I_APPROVER_NAME_CODE, IDEA.I_TITLE,IDEA.I_DESCRIPITION, IDEA.I_CREATED_DATE,IDEA.I_STATUS_CODE, "
+ "IDEA.I_IS_CODE, IDEA.I_CONTRIBUTION_CODE, IDEA.I_POSITIVE_IMPACT, IDEA.I_SECOND_MEMBER_ID,IDEA.I_THIRD_MEMBER_ID,IDEA.I_FOURTH_MEMBER_ID,"
+ "IDEA.I_FIFTH_MEMBER_ID, IDEA.I_POINTS,IDEA.I_CREATED_USER_ID)"
+ " VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
preparedStatement.executeQuery("SELECT IDEA_SEQ.nextval FROM DUAL");
// Set parameters
preparedStatement.setObject(1, Types.NUMERIC);
preparedStatement.setObject(2, Types.NUMERIC);
preparedStatement.setObject(3, addIdeaDto.getApproverNameCode());
preparedStatement.setString(4, addIdeaDto.getTitle());
preparedStatement.setString(5, addIdeaDto.getDescription());
preparedStatement.setDate(6, addIdeaDto.getCreatedDate() == null ? null
: new java.sql.Date(addIdeaDto.getCreatedDate().getTime()));
preparedStatement.setObject(7, addIdeaDto.getStatusCode());
preparedStatement.setObject(8, addIdeaDto.getIsNewCode());
preparedStatement.setObject(9, addIdeaDto.getContributionCode());
preparedStatement.setString(10, addIdeaDto.getPositiveImpact());
preparedStatement.setObject(11, addIdeaDto.getSecondMemberName());
preparedStatement.setObject(12, addIdeaDto.getThirdMemberName());
preparedStatement.setObject(13, addIdeaDto.getFourthMemberName());
preparedStatement.setObject(14, addIdeaDto.getFifthMemberName());
preparedStatement.setObject(15, addIdeaDto.getPoints());
preparedStatement.setInt(16, userId);
preparedStatement.executeQuery();
return addIdeaDto.getIdeaId();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
actually what I want is after or before the insert statement I want to get the id (IDEA_SEQ.nextval) and save it in a value in order to use it as an input to insert in anther table.
For example, I insert this record : id = 1 , no = 1, approver code = 2, title = 'test'.............
I want this value id = 1 to use it in order to insert in table A, A_id = 33, IDEA.I_ID = 1, A_name ='testing'
how i can achieve it in properer way?
I update the code based on the comments that i receive but I did not achieve it
Usually ID that need to be reuse can be handle using a previous and separate SQL query
previousPreparedStatement = connection.prepareStatement(
"select IDEA_SEQ.nextval as nextval from dual");
Result saved as a int or String parameter according to column (number or varchar) which is passed to the existing insert statement:
(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
Notice also an answer from DBA forum
you won't be able to use plain SQL to overcome this limitation: you will need some PL/SQL
A better way to handle this is the RETURNING INTO clause, which uses a single, atomic statement:
INSERT INTO mytable (id, col1, col2)
VALUES ( seq_id.nextval, c1, c2 )
RETURNING id INTO myval;
You can use PreparedStatement.getGeneratedKeys() to obtain the generated value. There is no need to use a separate statement:
You also can't prefix column names with the table name in list of columns of an INSERT statement.
String insert =
"INSERT INTO IDEA ( I_ID,I_NO,I_APPROVER_NAME_CODE, I_TITLE,I_DESCRIPITION, I_CREATED_DATE,I_STATUS_CODE, "
+ "I_IS_CODE, I_CONTRIBUTION_CODE, I_POSITIVE_IMPACT, I_SECOND_MEMBER_ID,I_THIRD_MEMBER_ID,I_FOURTH_MEMBER_ID,"
+ "I_FIFTH_MEMBER_ID, I_POINTS,I_CREATED_USER_ID)"
+ " VALUES (idea_seq.nextval,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
preparedStatement = connection.prepareStatement(insertSql, new String[] {"I_ID"});
preparedStatement.setInt(1, ???); // don't know where the value for I_NO comes from
preparedStatement.setString(2, addIdeaDto.getApproverNameCode());
preparedStatement.setString(3, addIdeaDto.getTitle());
... other parameters
preparedStatement.executeUpdate();
ResultSet rs = preparedStatement.getGeneratedKeys();
long newId = -1;
if (rs.next()) {
newId = rs.getLong("I_ID");
}
... use the NewId ...
The parameter new String[] {"I_ID"} for the prepareStatement() call tells the JDBC driver to return the generated value for that column. That value can be retrieved through getGeneratedKeys() which returns a ResultSet that contains one row for each inserted row (so exactly one in this case). The ID value can then be extracted from the ResultSet using the the usual getLong() (or getInt()) methods.

Where should ? be placed in a PreparedStatement? [duplicate]

This question already has an answer here:
Having a Column name as Input Parameter of a PreparedStatement
(1 answer)
Closed 7 years ago.
I am using PreparedStatement to select records from a table:
public static String getMemberInfo(String columnName, Integer memberId) {
String memberInfo = "";
String sql = "SELECT ? FROM member WHERE member_id = ?";
DatabaseConnector.setConn();
try(Connection conn = DatabaseConnector.getConn();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, columnName);
ps.setInt(2, memberId);
try(ResultSet rs = ps.executeQuery()) {
if(rs.next()) {
memberInfo = rs.getString(columnName);
}
}
} catch(SQLException se) {
se.printStackTrace();
}
return memberInfo;
}
When I use
SELECT " + columnName + " FROM member WHERE member_id = ?, it works.
But when I use
SELECT ? FROM member WHERE member_id = ?, it does not.
Where should ? be placed in prepared statements?
? is for input values (typically in the WHERE clause conditions).
? is not for selected columns.
Column name must be hard-coded, Only column values can be set using ?.
but you can set dynamic column name by doing something like this :
String sql = "SELECT "+ columnName +" FROM member WHERE member_id = ?";

Sorted Result Set from DB not apprearring in order while printed in Java

Finally narrowed down the problem, here is what my problem is when i execute a SQL which has 'order by' on that and try to print the result set in Java the result set is not sorted.
But when i execute the SQL separately with my SQL developer, I am seeing the ordered result why is that? Is there any option to solve this?
Below mentioned is method I am using
List getDBValues(short orderBy) throws Exception {
Connection conn = null;
ResultSet rs = null;
List results = nmull;
String sqlStmt = new String();
PreparedStatement ps = null;
try {
conn = Utilities.getConnection(DB);
sqlStmt ="SELECT
COLUMN1,
COLUMN2,
COLUMN3,
FROM SAMPLE_TABLE
WHERE
COLUMN1 IN ('10','15') AND
COLUMN3 IN ('1','2') ORDER BY ? ";
try {
short orderByObj = 0;
if(orderBy < 1){
orderByObj = Short.parseShort(Math.abs(orderBy)+"");
sqlStmt += "DESC";
}else{
orderByObj = orderBy;
}
System.out.println("==================== SQL ==================== \n"+sqlStmt);
ps = conn.prepareStatement(sqlStmt);
ps.setLong(1, orderByObj);
rs = ps.executeQuery();
while (rs.next())
System.out.println(rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
}
catch(SQLException e) {
e.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace()
}
return results;
}
You cannot use a bind variable within the order by statement.
You'll have to append it to the query.
sqlStmt ="SELECT
COLUMN1,
COLUMN2,
COLUMN3,
FROM SAMPLE_TABLE
WHERE
COLUMN1 IN ('10','15') AND
COLUMN3 IN ('1','2') ORDER BY ";
try {
short orderByObj = 0;
if(orderBy < 1){
orderByObj = Short.parseShort(Math.abs(orderBy)+"");
sqlStmt = sqlStmt + " " + orderByObj + " DESC";
}else{
sqlStmt = sqlStmt + " " + orderBy ;
}
System.out.println("==================== SQL ==================== \n"+sqlStmt);
ps = conn.prepareStatement(sqlStmt);
rs = ps.executeQuery();
while (rs.next())
System.out.println(rs.getString(1)+"\t"+rs.getString(2)+"\t"+rs.getString(3));
}
There might be problem with you JSP iterations.
Write out the codes you used here. Both i java, jsp.
Use LinkedList kind of collection stuff that stores data with respect to insertion order.
At the risk of being obvious, could it have anything to do with the fact that your SQL query doesn't actually sort the data? Maybe you mean to rewrite with a proper ORDER statement, such as, for example:
SELECT column1, column2 FROM table ORDER BY column1 DESC

How to check if a record with a specific primary key exists in a MySql table from JDBC

How can i find out, from a Java program using JDBC if my table has a record with a specific primary key value? Can i use the ResultSet somehow after i issue a SELECT statement?
Count might be a better idea for this case. You can use it like so:
public static int countRows(Connection conn, String tableName) throws SQLException {
// select the number of rows in the table
Statement stmt = null;
ResultSet rs = null;
int rowCount = -1;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName + " WHERE.... ");
// get the number of rows from the result set
rs.next();
rowCount = rs.getInt(1);
} finally {
rs.close();
stmt.close();
}
return rowCount;
}
Taken from here.
You can do something like
private boolean hasRecord(String id) throws SQLException {
String sql = "Select 1 from MyTable where id = ?";
PreparedStatement ps = dbConn.prepareStatement(sql);
ps.setString(1,id);
ResultSet rs = ps.executeQuery();
return rs.next();
}
You can do that in four steps.
Write SQL. Something like select count(1) from table where column = 34343 will do.
Learn how to get connection using JDBC.
Learn about PreparedStatements in Java.
Learn how to read values from ResultSet.
select case
when exists (select 1
from table
where column_ = '<value>' and rownum=1)
then 'Y'
else 'N'
end as rec_exists
from dual;

Oracle JDBC select with WHERE return 0

Similar question to:
Strange problem with JDBC, select returns null
but people didn't ask for this.
My code:
public int myMethod(String day) throws SQLException{
String sql = "Select count(*) from MyTable WHERE someColumn = " + day;
Connection connection = ConnFactory.get();
PreparedStatement prepareStatement = null;
ResultSet resultSet = null;
int ret = -1;
try{
prepareStatement = connection.prepareStatement(sql);
resultSet = prepareStatement.executeQuery(sql);
if(resultSet.next()){
ret = resultSet.getInt(1);
}
}
catch(SQLException sqle){
// closing statement & ResultSet, log and throw exception
}
finally{
// closing statement & ResultSet
}
ConnFactory.kill(connection);
return ret;
}
This code always return 0. I try to log sql before execution and try to run it in SQLdeveloper and get correct value (over 100).
When I remove WHERE, sql = "Select count(*) from MyTable query return number of all rows in table.
I use Oracle 10g with ojdbc-14.jar (last version from maven repo) and Java 6.
day has not been quoted correctly, I would suggest using a prepared statement like a prepared statement as follows:
...
try {
prepareStatement = connection.prepareStatement("Select count(*) from MyTable WHERE someColumn = ?");
prepareStatement.setString(1,day);
...
is the same as:
sql = "Select count(*) from MyTable WHERE someColumn = '" + day + "'";
with several advantages over the latter (mainly security and performance). See:
http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html
First of all using sql like this is not advisable. Because it leads to SQL injection.
In the future try using like below and use PreparedStatement to execute
String sql = "Select count(*) from MyTable WHERE someColumn = ? "
For your solution did you try
String sql = "Select count(*) from MyTable WHERE someColumn = '" + day + "'";
karim79 is good answer, you forgot add apostrophe signs in your "day" value
String sql = "Select count(*) from MyTable WHERE someColumn = '" + day + "'";

Categories