Check the null or empty record condition - sql

I wanted to know if I did this code well, to check if the coding of a record is null or empty, getTraduction (), if I did something wrong, just let me know where I went wrong.
because I would like to have even null records printed
public void getTraduttoreIt_CLASS_HDR_NLS() throws Exception {
List<ClassHdrNls> db2 = getListCLASS_HDR_NLS();
List<DizioPt> sqlServer = getListDizioPt();
BufferedWriter scrivi = new BufferedWriter(
new FileWriter("C:/Users/francesco/Desktop/Table_ClassHdrNls_Sez3.txt"));
for (int i = 0; i < db2.size(); i++) {
for (int j = 0; j < sqlServer.size(); j++) {
if (db2.get(i).getNlsClassName().equals(sqlServer.get(j).getKeyword())) {
System.out.println("-------------------FILE N°3---------------------------");
System.out.println("-------------------ITALIANO---------------------------");
System.out.println("CLASS_NAME: " + db2.get(i).getClassName());
scrivi.newLine();
scrivi.write("CLASS_NAME: ");
scrivi.write(db2.get(i).getClassName());
scrivi.newLine();
System.out.println("NLS_CLASS_NAME: " + db2.get(i).getNlsClassName());
scrivi.write("NLS_CLASS_NAME: ");
scrivi.write(db2.get(i).getNlsClassName());
scrivi.newLine();
System.out.println("NLS_PL_CLASS_NAME: " + db2.get(i).getNlsPlClassName());
scrivi.write("NLS_PL_CLASS_NAME: ");
scrivi.write(db2.get(i).getNlsPlClassName());
scrivi.newLine();
System.out.println("KEYWORD: " + sqlServer.get(j).getKeyword());
scrivi.write("KEYWORD: ");
scrivi.write(sqlServer.get(j).getKeyword());
scrivi.newLine();
System.out.println("LINGUA ITALIANO: " + db2.get(i).getLanguage() + " ***");
scrivi.write("LINGUA ITALIANO: ");
scrivi.write(db2.get(i).getLanguage() + " ***");
scrivi.newLine();
// Faccio un controllo se il valore è diverso da null o il record è vuoto
if (sqlServer.get(j).getTraduzione() == null || sqlServer.get(j).getTraduzione().isEmpty()) {
System.out.println("TRADUZIONE: ***********");
scrivi.write("TRADUZIONE: ");
scrivi.write("*******************");
scrivi.newLine();
} else {
System.out.println("TRADUZIONE: " + sqlServer.get(j).getTraduzione());
scrivi.write("TRADUZIONE: ");
scrivi.write(sqlServer.get(j).getTraduzione());
scrivi.newLine();
}
System.out.println("-------------------------------------------------------");
scrivi.flush();
}
}
}
scrivi.close();
}
Output:
Print only non-null and non-empty records.
I also want to print null records

this line:
if (db2.get(i).getNlsClassName().equals(sqlServer.get(j).getKeyword()))
could be why you are not printing null values, since it forces printing only after there is a match.
You should inspect your data (print all of it) to see what you are getting.
If you are finding null values, then that means printing inside the if condition is what's stopping you from seeing the null values get printed.

Related

DB2 - ERRORCODE=-4229, SQLSTATE=null

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();
}
}
...

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.

How to add dapper query parameters in a loop

When add query parameters for dapper in a loop,like this:
if (model.UserGroupId != null && model.UserGroupId.Count>0)
{
var list = model.UserGroupId;
sql += " and ( CHARINDEX(','+#group_id+',',','+mem.group_id+',')>0 ";
paras.Add("group_id", list[0].Trim());
for (var i = 1; i < list.Count(); i++)
{
string data = "#group_id" + i;
sql += " or CHARINDEX('," + data+ ",',','+mem.group_id+',')>0 ";
paras.Add(data, list[i].Trim());
}
sql += " )";
}
it does not report errors, but the query results are incorrect. I can't use dynamic # as a result of searching data. How can I solve this problem?
If I use this it can search correctly:
if (model.UserGroupId != null && model.UserGroupId.Count > 0)
{
var list = model.UserGroupId;
sql += " and ( CHARINDEX(','+#group_id+',',','+mem.group_id+',')>0 ";
paras.Add("group_id", list[0].Trim());
for (var i = 1; i < list.Count(); i++)
{
// string data = "#group_id" + i;
sql += " or CHARINDEX('," + list[i].Trim() + ",',','+mem.group_id+',')>0 ";
// paras.Add(data, list[i].Trim());
}
sql += " )";
}
But it has SQL injection problems.
var list = model.UserGroupId;
sql += " and ( CHARINDEX(','+#group_id+',',','+mem.group_id+',')>0 ";
paras.Add("group_id", list[0].Trim());
for (var i = 1; i < list.Count(); i++)
{
**sql += " or CHARINDEX(','+#group_id"+i+"+',',','+mem.group_id+',')>0 ";
paras.Add("#group_id" + i, list[i].Trim());**
}
sql += " )";
it can search rightly

SQL injection error in Dynamic SQL with prepared statement

I my application we are collection some user inputs from UI and based on those values we are generating dynamic SQLs with different 'Where' conditions to query data.
It is found that that piece of code has some SQL injection flaw.
public void filter(String strSerialNumberLogic, String strSerialNumber1,
String strSerialNumber2, String strCreationDateLogic,
long lngCreationDate1, long lngCreationDate2,
String strTypeNumbers, String strTitles, long lngLoc)
throws SQLException, ClassNotFoundException {
StringBuffer strWhere = new StringBuffer();
List paramList = new ArrayList();
String arrTypeNumbers[];
String arrTitles[];
int i;
boolean bolHit;
if (!strTypeNumbers.equals("") || !strTitles.equals("")) {
arrTypeNumbers = strTypeNumbers.split(",");
arrTitles = strTitles.split(",");
bolHit = false;
strWhere.append("(");
for (i = 0; i < arrTypeNumbers.length; i++) {
if (arrTypeNumbers[i].length() > 0) {
if (bolHit) {
strWhere.append(" OR ");
} else {
bolHit = true;
}
strWhere.append(" REPORT_NUMBER = ?");
paramList.add(arrTypeNumbers[i]);
}
}
for (i = 0; i < arrTitles.length; i++) {
if (arrTitles[i].length() > 0) {
if (bolHit) {
strWhere.append(" OR ");
} else {
bolHit = true;
}
strWhere.append(" REPORT_NAME = ?");
paramList.add(arrTitles[i]);
}
}
strWhere.append(") ");
}
if (!strSerialNumber1.equals("")) {
if (!strWhere.equals("")) {
strWhere.append(" AND ");
}
strWhere.append(" REPORT_FILE_NO " + strSerialNumberLogic + " ? ");
paramList.add(strSerialNumber1);
if (strSerialNumberLogic.equals("between")) {
strWhere.append(" AND ? ");
paramList.add(strSerialNumber2);
}
}
if (lngCreationDate1 != 0) {
if (!strWhere.equals("")) {
strWhere.append(" AND ");
}
strWhere.append(" REPORT_CREATION_DATE " + strCreationDateLogic + " ? ");
paramList.add(Long.toString(lngCreationDate1));
if (strCreationDateLogic.equals("between")) {
strWhere.append(" AND ? ");
paramList.add(Long.toString(lngCreationDate2));
}
}
if (lngLoc != 0) {
if (!strWhere.equals("")) {
strWhere.append(" AND ");
}
strWhere.append(" REPORT_FILE_LOCATION = ? ");
paramList.add(Long.toString(lngLoc));
}
String finalQuery = "";
if (!strWhere.equals("")) {
finalQuery = "WHERE " + strWhere.toString();
}
String strSQL = "SELECT * " + "FROM D990800 "
+ "LEFT JOIN D990400 ON REPORT_SYSTEM_ID ||" + " REPORT_NO = REPORT_NUMBER " + finalQuery
+ "ORDER BY REPORT_FILE_NO ASC";
System.out.println("strSQL:" + strSQL );
System.out.println("paramList:" + paramList );
Connection conn = ConnectionFactory.instance().getConnection();
PreparedStatement preparedStatement = null;
preparedStatement = conn.prepareStatement(strSQL);
for (int index = 0; index < paramList.size(); index++) {
String param = (String) paramList.get(index);
if (isParsableInt(param)) {
preparedStatement.setInt(index+1, Integer.parseInt(param));
} else {
preparedStatement.setString(index+1, param);
}
}
ResultSet rsReports = preparedStatement.executeQuery();
buildCollection(rsReports);
rsReports.close();
preparedStatement.close();
conn.close();
}
How did you come to the conclusion that you have SQL injection in this code? That would help clearing that up.
Anyway, looking at your code it seems that both strSerialNumberLogic and strCreationDateLogic are variables that comes from an external source, and are concatinated in a way that allows SQL to be injected. If this external source is the user, SQL injection can be executed. If not, than this is probably a false positive. I would improve the code anyway by chaning the logic variables turning them into Enums.

How do I print elements in an ArrayList without the null?

This is what I tried doing..
public void printArray()
{
for(int i = 0; i<size; i++)
{
System.out.println("arr[" + i + "] = " + arr[i]);
}
}
this is what I get:
-arr[0] = Papa Bill
-arr[1] = Ali Baba
-arr[2] = Ming the Merciless
-arr[3] = Grandpa
-arr[4] = Tornado
-arr[5] = null
I need it to print with out null...
Just add a check for null in your for loop:
if ( arr[i] != null ){
System.out.println("arr[" + i + "] = " + arr[i]);
}