DB2 - ERRORCODE=-4229, SQLSTATE=null - sql

I'm using a batch class in EJB to INSERT more than 100 rows in the same commit using the command line executeBatch in the DB2.
When I execute the command shows this error: ERRORCODE=-4229, SQLSTATE=null.
The ID sequence is IDENTITY clause on the CREATE TABLE.
Table:
CREATE TABLE table (col1 INT,
col2 DOUBLE,
col3 INT NOT NULL GENERATED ALWAYS AS IDENTITY)
Does anyone have any idea?
ERROR:
Caused by: nested exception is: com.ibm.db2.jcc.am.BatchUpdateException: [jcc][t4][102][10040][4.24.97] Batch failure. The batch was submitted, but at least one exception occurred in an individual batch member.
Use getNextException() to retrieve exceptions for specific batch elements. ERRORCODE=-4229, SQLSTATE=null

It's not an answer, but a suggestion to handle Db2 exceptions to have an ability to deal with such errors.
If you are unable to rewrite your error handling, the only thing you can to is to enable JDBC trace on the client or/and set the Db2 dbm cfg DIAGLEVEL parameter to 4.
PreparedStatement pst = null;
try
{
pst = ...;
...
int [] updateCounts = pst.executeBatch();
System.out.println("Batch results:");
for (int i = 0; i < updateCounts.length; i++)
System.out.println(" Statement " + i + ":" + updateCounts[i]);
} catch (SQLException ex)
{
while (ex != null)
{
if (ex instanceof com.ibm.db2.jcc.DB2Diagnosable)
{
com.ibm.db2.jcc.DB2Diagnosable db2ex = com.ibm.db2.jcc.DB2Diagnosable) ex;
com.ibm.db2.jcc.DB2Sqlca sqlca = db2ex.getSqlca();
if (sqlca != null)
{
System.out.println("SQLCODE: " + sqlca.getSqlCode());
System.out.println("MESSAGE: " + sqlca.getMessage());
}
else
{
System.out.println("Error code: " + ex.getErrorCode());
System.out.println("Error msg : " + ex.getMessage());
}
}
else
{
System.out.println("Error code (no db2): " + ex.getErrorCode());
System.out.println("Error msg (no db2): " + ex.getMessage());
}
if (ex instanceof BatchUpdateException)
{
System.out.println("Contents of BatchUpdateException:");
System.out.println(" Update counts: ");
System.out.println(" Statement.SUCCESS_NO_INFO: " + Statement.SUCCESS_NO_INFO);
System.out.println(" Statement.EXECUTE_FAILED : " + Statement.EXECUTE_FAILED);
BatchUpdateException buex = (BatchUpdateException) ex;
int [] updateCounts = buex.getUpdateCounts();
for (int i = 0; i < updateCounts.length; i++)
System.out.println(" Statement " + i + ":" + updateCounts[i]);
}
ex = ex.getNextException();
}
}
...

Related

Prepare Statement very slow compare with direct query | Oracle DB

I have a prepared statement in my application and it takes 3 minutes to give an results. However, same query i have executed in sql developer and it only takes less than 0.1 seconds to give the results. I have done research on this throughout last week and I couldn't find a proper solution. Here is my code.
public List<ResponseDto> loadData(RequestDto request) throws SQLException {
List<ResponseDto> responseDto = new ArrayList<>();
int sortBy = request.getSortBy();
String sql = "SELECT *" +
"FROM (SELECT r.*, ROWNUM RNUM, COUNT(*) OVER () RESULT_COUNT " +
" FROM (SELECT *" +
"FROM" +
" (SELECT r.VALUE_4," +
" r.DATE," +
" r.ID," +
" r.AMOUNT," +
" r.TO_AGENT_ID," +
" r.FROM_AGENT_ID," +
" a.NAME," +
" r.VALUE_2," +
" r.VALUE_1," +
" r.STATUS," +
" r.VALUE_3," +
" r.TEXT" +
" FROM MY_TABLE r" +
" INNER JOIN AGENT a " +
" ON a.AGENT_ID=r.TO_AGENT_ID" +
" WHERE r.STATUS = 1 " +
" AND r.ID IN" +
" (SELECT T.ID FROM TEST_TABLE T" +
" INNER JOIN AGENT af" +
" ON af.AGENT_ID = T.FROM_AGENT_ID " +
" INNER JOIN AGENT at" +
" ON at.AGENT_ID=T.TO_AGENT_ID" +
" WHERE T.FROM_AGENT_ID=?";
StringBuilder sbQuery = new StringBuilder(sql);
if (request.getToAgentId() != 0) {
sbQuery.append(" AND T.TO_AGENT_ID = ? ");
} else if (request.getQueryParam() != null && !request.getQueryParam().equalsIgnoreCase("")) {
sbQuery.append(" AND UPPER(at.NAME) like UPPER( ? ) ");
}
String secondPart =
" AND T.STATUS = 1" +
" AND TO_DATE(T.DATE) BETWEEN TO_DATE(?, 'yyyy-MM-dd') AND TO_DATE(?, 'yyyy-MM-dd')" +
" ) " +
" or r.VALUE_3=?";
sbQuery.append(secondPArt);
if (sortBy == 1) {
sbQuery.append(" ORDER BY a.NAME ");
} else if (sortBy == 2) {
sbQuery.append(" ORDER BY r.AMOUNT ");
} else if (sortBy == 3) {
sbQuery.append(" ORDER BY r.VALUE_4 ");
}
if (request.getSortingOrder() == 1) {
sbQuery.append("DESC ");
} else if (request.getSortingOrder() == 2) {
sbQuery.append("ASC ");
}
sbQuery.append(" )) R)" +
"WHERE RNUM between ? and ?");
String sqlq = sbQuery.toString();
log.info(sqlq);
try(Connection con = dataSource.getConnection(); PreparedStatement pstmt = con.prepareStatement(sbQuery.toString()) ) {
con.setAutoCommit(false);
String nameParam = "%" + request.getQueryParam() + "%";
pstmt.setLong(1, request.getFromAgentId());
if (request.getToAgentId() != 0) {
pstmt.setLong(2, request.getToAgentId());
} else if(request.getQueryParam() != null && !request.getQueryParam().equalsIgnoreCase("")) {
pstmt.setString(2, request.getQueryParam());
}
pstmt.setString(3, request.getFromDate());
pstmt.setString(4, request.getToDte());
pstmt.setString(5, request.getQueryParam());
pstmt.setLong(6, request.getFromIndex());
pstmt.setLong(7, request.getToIndex());
responseDto = helperMethod(pstmt);
con.commit();
} catch (SQLException e) {
log.error(e.getMessage());
throw e;
}
return responseDto;
}
public List<MyDto> helperMethod(PreparedStatement pstmt) throws SQLException {
List<MyDto> myDtoList = new ArrayList<>();
try( ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
MyDto myDto = new MyDto();
myDto.setValue4(rs.getLong("VALUE_4"));
myDto.setDate(rs.getDate("DATE"));
myDto.setTransactionId(rs.getLong("ID"));
myDto.setAmount(rs.getLong("AMOUNT"));
myDto.setToAgentId(rs.getLong("TO_AGENT_ID"));
myDto.setFromAgentId(rs.getLong("FROM_AGENT_ID"));
myDto.setName(rs.getString("NAME"));
myDto.setValue2(rs.getLong("VALUE_2"));
myDto.setValue1(rs.getLong("VALUE_1"));
myDto.setStatus(rs.getInt("STATUS"));
myDto.setValue3(rs.getString("VALUE_3"));
myDto.setText(rs.getString("TEXT"));
myDtoList.add(myDto);
}
}catch (Exception ex){
log.error(ex.getMessage());
throw ex;
}
return myDtoList;
}
As I said, same query works with in milliseconds. I really don't know what i am doing wrong here.
Any help would be grateful !
This is not a direct answer, but may hopefully point you in the right direction. First off, depending on your conditionals, there are different variations of what SQL is executed. I would try the following:
Edit the select string and embed a unique comment in it so we can find it in the next step. Example : "select /*mytest*/ * from ..."
Execute your program. Then locate the query in the v$sqlarea such as: select sql_id from v$sqlarea where instr(sql_fulltext,'mytest') > 0;
using the sql_id value from Step #2, execute SELECT * FROM table(DBMS_XPLAN.DISPLAY_CURSOR('sql_id',0));
this will show you the execution plan, and hopefully you will see the difference maybe a full table scan is happening or index not getting used. etc. Do similar steps for the direct sql query that is faster and see what the differences are.

Gettint try and catch events after deleting row sql

Hello guys whenever I try to delete a row using a radiobutton, I get both try and catch messages, when it is supposed to be just 1 of them, I have this code
Here's my calling button method
if(request.getParameter("btnEliminar") != null)
{
String value;
int codParse;
OC_DAO objDAO = new OC_DAO();
valor = request.getParameter("rbSel");
codParse = Integer.parseInt(valor);
objDAO.DeleteRow(codParse);
}
Here's my java code
public void DeleteRow(int codDet)
{
try
{
cn = Conexion.getConexion();
pt = cn.prepareStatement("DELETE "
+ "FROM detalleProd "
+ "WHERE codDet = ?");
pt.setInt(1, codDet);
pt.executeUpdate();
System.out.println("ROW DELETED ON CODDET: " + codDet);
rs.close();
pt.close();
cn.close();
}
catch(Exception exc)
{
System.out.println("Error while deleting");
System.out.println(exc.toString());
}
}
And here's my log
Información: ROW DELETED ON CODDET: 48
Información: Error while deleting
Información: java.lang.NullPointerException
The reason is due to rs.close();, you have not set value of rs,it's null and can not be closed,you just need to remove this line of code.
Your code seems very strange,I do not have see where you declare rs,it will compile error in your IDE.

BigQuery Java API not returning all rows when we execute query through it

We are facing one intermittent issue where when we execute a query though BigQuery Java API then the number of rows that we get doesn't match with when we execute the same query through BigQuery UI.
In our code, we are using QueryResponse object for executing a query and we also check whether query is completed or not by checking the flag
GetQueryResultsResponse.getJobComplete(), we also have mechanism to pull more records if the query is not returning all rows in one short while(queryResult.getRows() != null && queryResult.getTotalRows().compareTo(BigInteger.valueOf((queryResult.getRows().size()))) > 0) {
Following is the piece of code which we use for executing the query:
int retryCount = 0;
long waitTime = Constant.BASE_WAIT_TIME;
Bigquery bigquery = cloudPlatformConnector.connectBQ();
QueryRequest queryRequest = new QueryRequest();
queryRequest.setUseLegacySql(useLegacyDialect);
GetQueryResultsResponse queryResult = null;
GetQueryResultsResponse queryPaginationResult = null;
String pageToken;
do{
try{
QueryResponse query = bigquery.jobs().query(this.projectId, queryRequest.setQuery(querySql)).execute();
queryResult = bigquery.jobs().getQueryResults(query.getJobReference().getProjectId(), query.getJobReference().getJobId()).execute();
if(queryResult != null ){
if(!queryResult.getJobComplete()){
LOGGER.info("JobId for the query : "+ query.getJobReference().getJobId() + " is Job Completed : "+ queryResult.getJobComplete());
if(queryResult.getErrors() != null){
for( ErrorProto err: queryResult.getErrors() ){
LOGGER.info("Errors in query, Reason : "+ err.getReason()+ " Location : "+ err.getLocation() +" Message : "+ err.getMessage());
}
}
LOGGER.info("Query not completed : "+querySql);
throw new IOException("Query is failing retrying it");
}
}
LOGGER.info("JobId for the query : "+ query.getJobReference().getJobId() + " is Job Completed : "+ queryResult.getJobComplete() + " Total rows from query : " + queryResult.getTotalRows());
pageToken = queryResult.getPageToken();
while(queryResult.getRows() != null && queryResult.getTotalRows().compareTo(BigInteger.valueOf((queryResult.getRows().size()))) > 0) {
LOGGER.info("Inside the Pagination code block, Page Token : "+pageToken);
queryPaginationResult = bigquery.jobs().getQueryResults(projectId,query.getJobReference().getJobId()).setPageToken(pageToken).setStartIndex(BigInteger.valueOf(queryResult.getRows().size())).execute();
queryResult.getRows().addAll(queryPaginationResult.getRows());
pageToken = queryPaginationResult.getPageToken();
LOGGER.info("Inside the Pagination code block, total size : "+ queryResult.getTotalRows() + " Current Size : "+ queryResult.getRows().size());
}
}catch(IOException ex){
retryCount ++;
LOGGER.info("BQ Connection Attempt "+retryCount +" failed, Retrying in " + waitTime + " seconds");
if (retryCount == Constant.MAX_RETRY_LIMIT) {
LOGGER.info("BQ Connection Error", ex);
throw ex;
}
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
LOGGER.info("Thread Error");
}
waitTime *= 2;
}
}while((queryResult == null && retryCount < Constant.MAX_RETRY_LIMIT ) || (!queryResult.getJobComplete() && retryCount < Constant.MAX_RETRY_LIMIT));
return queryResult.getRows();
The Query in which I am not getting all rows doesn't have any limit clause in it.
Currently we are using 0.5.0 version of google-cloud-bigquery.
Thanks in Advance!
I think on subsequent calls of getQueryResults, you need to call setPageToken properly with the pageToken returned from the previous page. Otherwise getQueryResults would just return the rows from the first page.

Increasing the size of Varchar2() in oracle

Is it possible to increment the size of a column (say varchar2(25)) by 50? To be precise, I am not looking for something like this:
ALTER TABLE <Table_name> modify <Column_name> varchar2(75);
Rather, I am inquisitive about something that will increase the size by 50 or some other integer constant without the explicit calculation on the programmer part.
PS: Please comment if I am not clear.
Just to be clear, it appears you're asking for a way to add a fixed value to the column size without knowing what the original size is (hence asking how to add 50 and disallowing setting it directly to 75, which would require knowing it was 25 to start with).
Most databases provide system tables or views which give you the metadata about various objects. For example, DB2/z has sysibm.syscolumns and Oracle has all_tab_columns as shown in this link.
If you wanted to expand the column by 50 without knowing in advance what the size was, you could simply consult the metadata to get the current size and just add 50, constructing a statement to do it for you.
In other words, use something like:
select char_length from all_tab_columns
where owner = '<Table_owner>'
and table_name = '<Table_name>'
and column_name = '<Column_name>'
then extract that number from the recordset, add 50, and use that to dynamically construct and execute an alter table statement, similar to the one in your question that assumes you already know the length you want.
You can also use the user_tab_columns view if you're only concerned with your own tables rather than all those you can see. In that case, you don't need to concern yourself with the where owner = clause.
Although this sample code is specific to the DB2/z metadata, it wouldn't take much to convert it to the corresponding Oracle version:
import java.io.*;
import java.util.*;
import java.sql.*;
class chgcolsz {
public void chgcolsz() {}
public static void main (String args[]) {
Connection conn;
try {
Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();
conn = DriverManager.getConnection(
"jdbc:db2://MyBox:9999/MyInstance", "Me", "MyPassword");
conn.setAutoCommit (true);
} catch (Exception e) {
System.out.println ("** Error: DB connect: " + e);
e.printStackTrace();
return;
}
String cmd =
"select length from sysibm.syscolumns" +
" where tbcreator = 'PAX'" +
" and tbname = 'XYZZY'" +
" and name = 'COLUMN1'";
ResultSet rs;
try {
Statement sttmnt = conn.createStatement();
rs = sttmnt.executeQuery (cmd);
} catch (Exception e) {
rs = null;
System.out.println ("** Warning: rowset create: '" +
cmd + "': " + e);
e.printStackTrace();
}
int sz = -1;
if (rs != null) {
try {
rs.next();
sz = rs.getInt(1);
rs.close();
} catch (Exception e) {
System.out.println ("** Warning: rowset close: " + e);
e.printStackTrace();
};
}
if (sz != -1) {
System.out.println ("Current size is " + sz);
cmd = "alter table pax.xyzzy" +
" alter column column1" +
" set data type" +
" varchar(" + (sz + 50) + ")";
System.out.println ("Executing: " + cmd);
try {
Statement sttmnt = conn.createStatement();
sttmnt.execute (cmd);
} catch (Exception e) {
System.out.println ("** Warning: table alter: '" +
cmd + "': " + e);
e.printStackTrace();
}
}
try {
conn.close();
} catch (Exception e) {
System.out.println ("** Warning: DB close: " + e);
e.printStackTrace();
};
}
}
You can see from subsequent runs of this program that it's increasing the column width by 50 each time:
pax> java chgcolsz
Current size is 50
Executing: alter table pax.xyzzy alter column column1 set data type varchar(100)
pax> java chgcolsz
Current size is 100
Executing: alter table pax.xyzzy alter column column1 set data type varchar(150)
pax> java chgcolsz
Current size is 150
Executing: alter table pax.xyzzy alter column column1 set data type varchar(200)

postgres crosstab parameter

I have a crosstab query (using postgres) using prepared statement
I'm trying to add a parameter (center) but it is not working here's my code:
public List<openbookBean> summarylist(String center) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
String querystring = "select team_manager as team_manager2, "
+ "compliance_1 as day1, "
+ "compliance_2 as day2, "
+ "compliance_3 as day3 "
+ "FROM crosstab('select team_manager, date_compliance, compliance from openbook_comp where("
+ "extract(day from date_compliance)= ''1'' or "
+ "extract(day from date_compliance)= ''2'' or "
+ "extract(day from date_compliance)= ''3'') "
+ "and center = '''?''' "
+ "order by 1,2') AS openbook_comp (team_manager text, "
+ "compliance_1 varchar,"
+ "compliance_2 varchar,"
+ "compliance_3 varchar)";
List<openbookBean> summarylist_array = new ArrayList<openbookBean>();
try {
connection = database.getConnection();
statement = connection.prepareStatement(querystring);
statement.setString(1, center);
resultSet = statement.executeQuery();
while (resultSet.next()) {
openbookBean summarylistarray = new openbookBean();
summarylistarray.setTeam_manager2(resultSet.getString("team_manager2"));
summarylistarray.setDay1(resultSet.getString("day1"));
summarylistarray.setDay2(resultSet.getString("day2"));
summarylistarray.setDay3(resultSet.getString("day3"));
summarylist_array.add(summarylistarray);
}
} finally {
try { resultSet.close(); } catch (SQLException logOrIgnore) {}
try { statement.close(); } catch (SQLException logOrIgnore) {}
try { connection.close(); } catch (SQLException logOrIgnore) {}
}
return summarylist_array;
}
}
and here is a part of the servlet
if (request.getParameter("show").equals("summary")) {
try {
List<openbookBean> summarylist_array = openbookDAO.summarylist(region);
request.setAttribute("summarylist_array", summarylist_array);
request.getRequestDispatcher("summary.jsp").forward(request, response);
}
catch (SQLException e) {
throw new ServletException("Cannot retrieve areas", e);
}
}
I always getting this error:
java.lang.NullPointerException
source.openbookDAO.summarylist(openbookDAO.java:358)
source.openbookServlet.doGet(openbookServlet.java:74)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
You are not closing the last parenthesis and there is an extra comma:
+ "order by 1,2') AS openbook_comp (team_manager text, "
+ "compliance_1 varchar,"
+ "compliance_2 varchar,"
+ "compliance_3 varchar)"
And you can use this:
+ "extract(day from date_compliance) in (1, 2, 3) "
If center is numeric don't use quotes and add a space after the parameter:
+ "and center = ? "
If it is not numeric try it like this:
+ "and center = '''?''' "