SQL INSERT INTO does not work properly (in Java) - java

I have sql code in java class. The code is just like this below.
private void SummTEkspor(){
try {
bln = (String) cmbBln.getSelectedItem();
thn = (String) cmbThn.getSelectedItem();
String sql1 ="DELETE FROM a.dbo.t_export";
String sql2 ="INSERT INTO a.dbo.t_export\n" +
"SELECT * FROM b.dbo.export b WHERE b.sk_batch IN \n" +
"(SELECT sk_batch from batch_hdr WHERE bln_proses="+bln+
"AND thn_proses="+thn;
Statement st = kon.conn.createStatement();
int rs = st.executeUpdate(sql1);
int rsl = st.executeUpdate(sql2);
} catch (Exception x) {
System.out.println("FAILED");;
}
}
when i run the sql1, it works, but when sql2, it did not work properly, and just display FAILED . I guess the query in sql2 didn't take any value from what selected combo box. How can i solve that? Thanks for any reply

The problem is because you query is not proper :
INSERT INTO a.dbo.t_export\n" +
"SELECT * FROM b.dbo.export b WHERE b.sk_batch IN \n" +
"(SELECT sk_batch from batch_hdr WHERE bln_proses="+bln+
"AND thn_proses="+thn;
When you are creating a second select sub-query, you have not closed the ) bracket.
Try this :
INSERT INTO a.dbo.t_export" +
"SELECT * FROM b.dbo.export b WHERE b.sk_batch IN " +
"(SELECT sk_batch from batch_hdr WHERE bln_proses='"+bln+
"' AND thn_proses='"+thn + "')";

You open a bracket in (SELECT sk_batch f and never close it.
Use System.out.println(sql2); in order to see how the second query looks like, it could also be that one of the parameters thn and bln are null for example.

Fix the Query, quote the string values and put proper spaces.
String bln="testing";
String thn="abc";
String sql2 ="INSERT INTO a.dbo.t_export\n" +
"SELECT * FROM b.dbo.export b WHERE b.sk_batch IN \n" +
"(SELECT sk_batch from batch_hdr WHERE bln_proses='"+bln+
"' AND thn_proses='"+thn+"')";

Maybe there are som ereasons:
- closing braket in second select statement
- if bln_proses or thn_proses are strings then you have to use ' character to encompass the values

First of all you have put \n in your queries which is unnecessary, then Qualifying the table a.dbo.t_export is not needed.
Instead of:
String sql2 ="INSERT INTO a.dbo.t_export\n" +
"SELECT * FROM b.dbo.export b WHERE b.sk_batch IN \n" +
"(SELECT sk_batch from batch_hdr WHERE bln_proses="+bln+
"AND thn_proses="+thn;
Try:
String sql2 ="INSERT INTO dbo.t_export " +
"SELECT * FROM b.dbo.export b WHERE b.sk_batch IN " +
"(SELECT sk_batch from batch_hdr WHERE bln_proses="+bln+
" AND thn_proses="+thn +")";
If your columns are of Varchar type then you have to put values inside '' (Single Quotes).
Above query will work. But I suggest you to not use this approach because there is a chance of SQL Injection. Use Precompiled statements to avoid SQL Injection.

Try this query
String sql2 ="INSERT INTO a.dbo.t_export" +
"SELECT * FROM b.dbo.export b WHERE b.sk_batch IN " +
"(SELECT sk_batch from batch_hdr WHERE bln_proses="+bln+
"AND thn_proses="+thn+ ")";
bln_proses & thn_proses these are from same table batch_hdr ???

Related

Bad SQL grammar -The column name was not found in this ResultSet?

Hello I am using a JDBC query and I am having this error but I don't understand why, or what exactly is the meaning of this error and what is wrong with the query.
The query is as below
private List<StatisticsLog> runStatistics(Integer partnerId, LocalDate ldStart, LocalDateTime ldtEnd, String statType)
{
return jdbcTemplate.query("SELECT S.APP_ID, S.LOG_TYPE, ACC.CONTACT_PERSON_FIRST_NAME, ACC.CONTACT_PERSON_LAST_NAME, ACV.VERSION_APP_NAME, "
+ "'" + statType.trim() + "' STATTYPE, "
+ "ACV.APP_CATALOG_ID, ACV.APP_CATALOG_VERSION_ID, ACV.VERSION, ACV.UPDATED_AT, ACV.VERSION_LOGO_EXT, ACV.HAS_LOGO, "
+ "LANG.LANGUAGE_NAME_SHORT, LANG.LANGUAGE_ID , S.count, S.PARTNER_ID, APP.CREATED_AT "
+ "FROM (SELECT partner_id, log_type, app_id, language_id, count(*) as count FROM public.statistics_log "
+ " WHERE partner_id = ? "
+ " and logged_at between ? and ? "
+ "group by 1, log_type, app_id, language_id) as S "
+ "INNER JOIN APP_CATALOG_ACCOUNT ACP ON ACP.APP_CATALOG_SERIAL_ID = S.APP_ID "
+ "INNER JOIN APP_CATALOG APP ON APP.APP_CATALOG_SERIAL_ID = S.APP_ID "
+ "INNER JOIN ACCOUNT ACC ON ACC.ACCOUNT_ID = S.PARTNER_ID "
+ "INNER JOIN APP_CATALOG_VERSION ACV on ACV.APP_CATALOG_SERIAL_ID = APP.APP_CATALOG_SERIAL_ID AND ACV.STATUS = 3 "
+ "INNER JOIN LANGUAGE LANG ON LANG.LANGUAGE_ID = ACV.LANGUAGE_ID "
+ "ORDER BY S.count desc ",
new Object[] { partnerId, ldStart, ldtEnd }, new StatisticsLogRowMapper());
}
and I am getting the error from this column CREATED_AT that is part of the app catalog, and I think it should be there, also for more detailed also I will attach StatisticsLogRowMapper
public class StatisticsLogRowMapper implements RowMapper<StatisticsLog>
{
#Override
public StatisticsLog mapRow(ResultSet rs, int rowNum) throws SQLException
{
StatisticsLog stat = new StatisticsLog();
stat.setAppId(rs.getInt("APP_ID"));
stat.setPartnerId(rs.getInt("PARTNER_ID"));
stat.setCount(rs.getLong("COUNT"));
stat.setCreatedAt(rs.getTimestamp("CREATED_AT").toLocalDateTime());
stat.setPartnerFirstName(rs.getString("CONTACT_PERSON_FIRST_NAME"));
stat.setPartnerLastName(rs.getString("CONTACT_PERSON_LAST_NAME"));
stat.setAppNameDefault(rs.getString("VERSION_APP_NAME"));
stat.setAppCatalogId(rs.getInt("APP_CATALOG_ID"));
stat.setStatType(rs.getString("STATTYPE"));
stat.setLogType(LogTypeEnum.valueOf(rs.getString("LOG_TYPE").trim()));
stat.setAppCatalogVersionId(rs.getInt("APP_CATALOG_VERSION_ID"));
stat.setVersion(rs.getInt("VERSION"));
stat.setUpdatedAt(rs.getDate("UPDATED_AT"));
stat.setVersionLogoExt(rs.getString("VERSION_LOGO_EXT"));
stat.setHasLogo(rs.getBoolean("HAS_LOGO"));
stat.setLanguageNameShort(rs.getString("LANGUAGE_NAME_SHORT"));
stat.setLanguageId(rs.getInt("LANGUAGE_ID"));
return stat;
}
}
THE ERROR IS: "PreparedStatementCallback; bad SQL grammar [SELECT S.APP_ID, S.LOG_TYPE, ACC.CONTACT_PERSON_FIRST_NAME, ACC.CONTACT_PERSON_LAST_NAME, ACV.VERSION_APP_NAME, 'days30' STATTYPE, ACV.APP_CATALOG_ID, ACV.APP_CATALOG_VERSION_ID, ACV.VERSION, ACV.UPDATED_AT, ACV.VERSION_LOGO_EXT, ACV.HAS_LOGO, LANG.LANGUAGE_NAME_SHORT, S.count, S.PARTNER_ID FROM (SELECT partner_id, log_type, app_id, language_id, count(*) as count FROM public.statistics_log WHERE logged_at between ? and ? group by 1, log_type, app_id, language_id, partner_id) as S INNER JOIN APP_CATALOG_ACCOUNT ACP ON ACP.APP_CATALOG_SERIAL_ID = S.APP_ID INNER JOIN APP_CATALOG APP ON APP.APP_CATALOG_SERIAL_ID = S.APP_ID INNER JOIN ACCOUNT ACC ON ACC.ACCOUNT_ID = S.PARTNER_ID INNER JOIN APP_CATALOG_VERSION ACV on ACV.APP_CATALOG_SERIAL_ID = APP.APP_CATALOG_SERIAL_ID AND ACV.STATUS = 3 INNER JOIN LANGUAGE LANG ON LANG.LANGUAGE_ID = ACV.LANGUAGE_ID ORDER BY S.count desc ]; nested exception is org.postgresql.util.PSQLException: The column name CREATED_AT was not found in this ResultSet."
IN THE ERROR SEEMS THIS FIELD ISN'T THERE SOMEHOW
If you have any idea what may be wrong or thing I can try please don't hesitate to comment, I would appreciate d even the smallest help thank you.
I can see there is an error in line 2 of the query - + "'" + statType.trim() + "' STATTYPE, ", right after the quote. STATTYPE does not have a table reference and is appended with a string. That could be another issue. I cannot comment on the question as I dont have enough reputation.

Java + JDBC: Prepared statement failing

I'm trying to make a prepared statement and the drivers are working how I assume they are supposed to but the only problem is that my query is no longer valid.
I'm trying to write this query:
SELECT ip_address
FROM log_activity
WHERE created_at
BETWEEN "2017-01-01 00:00:00"
AND DATE_ADD("2017-01-01 00:00:00", INTERVAL 1 HOUR)
GROUP BY ip_address
HAVING COUNT(*) > 200;
But after inserting the parameters for the prepared statement it comes out as:
SELECT ip_address
FROM log_activity
WHERE created_at
BETWEEN '\'2017-01-01 00:00:00\''
AND DATE_ADD('\'2017-01-01 00:00:00\'', INTERVAL 1 'hour')
GROUP BY ip_address
HAVING COUNT(*) > 200;
Which is no longer valid SQL. So how do I remove these quotations from the parameters or what is a good way to work around this?
...
String startDateArg = "'" + args[0].split("=", 2)[1].replace(".", " ") + "'";
String durationArg = args[1].split("=", 2)[1];
int thresholdArg = Integer.parseInt(args[2].split("=", 2)[1]);
String duration = durationArg.equals("hourly") ? "hour" : durationArg.equals("daily") ? "day" : null;
String getUsersOverAPILimitQuery = "" +
"select ip_address " +
"from log_activity " +
"where created_at " +
" between ?" +
" and date_add(?, interval 1 ?) " +
"group by ip_address " +
"having count(*) > ?;";
PreparedStatement preparedStatement = con.prepareStatement(getUsersOverAPILimitQuery);
preparedStatement.setString(1, startDateArg);
preparedStatement.setString(2, startDateArg);
preparedStatement.setString(3, duration);
preparedStatement.setInt(4, thresholdArg);
System.out.println(preparedStatement);
ResultSet getUsersOverAPILimit = preparedStatement.executeQuery();
while (getUsersOverAPILimit.next()) {
String ip_address = getUsersOverAPILimit.getString("ip_address");
System.out.println(ip_address);
}
...
Instead of this:
String startDateArg = "'" + args[0].split("=", 2)[1].replace(".", " ") + "'";
Do this:
String startDateArg = args[0].split("=", 2)[1].replace(".", " ");
no need to add in the single quotes, the preparedstatement does it for you.

Launching two query via java code

I want to execute two queries in my PostgreSQL database via code java.
The first one create a temporary view and the second one get some data from this view.
This is my code:
String sql = "create or replace temp view recap as "
+ "select id_salarie, concat(nom, ' ', prenom) as np, hour_salary, id_chantier, id_activity, SUM(nb_heures) as s_hn, SUM(nb_heures_s) as s_hs, value_update, (hour_salary*SUM(nb_heures)) as cost_hn, ((hour_salary*value_update)*SUM(nb_heures_s)) as cost_hs "
+ "from pointage_full pf, salarie s, hs_increase hsi "
+ "where s.id = pf.id_salarie "
+ "and hsi.etat = 1 "
+ "and id_chantier = "+this.idProject+" and id_salarie <> id_chef "
+ "group by id_salarie, np, hour_salary, id_activity, id_chantier, value_update "
+ "order by id_salarie DESC;"
+ ""//=================execute the second query to get costs from created view===========================
+ "select id_activity, sum(cost_hn) as sm_cost_hn, sum(cost_hs) as sm_cost_hs, (sum(cost_hn)+sum(cost_hs)) as cost_activity "
+ "from recap "
+ "group by id_activity "
+ "order by id_activity asc;";
ResultSet res = state.executeQuery(sql);
while (res.next()) {
//---doing my stuff...
}
But I get this error:
org.postgresql.util.PSQLException: No results returned by the query.
You cannot execute more than one statement with a single executeXXX() call - especially not a DDL statement and a query.
But you don't need to create that (temporary) view in the first place. Also the order by inside the view is also useless as you are re-ordering the rows in the final statement again.
You can do what you want with one single statement:
select id_activity, sum(cost_hn) as sm_cost_hn, sum(cost_hs) as sm_cost_hs, (sum(cost_hn)+sum(cost_hs)) as cost_activity
from (
select id_salarie,
concat(nom, ' ', prenom) as np,
hour_salary,
id_chantier,
id_activity,
SUM(nb_heures) as s_hn,
SUM(nb_heures_s) as s_hs,
value_update,
(hour_salary*SUM(nb_heures)) as cost_hn,
((hour_salary*value_update)*SUM(nb_heures_s)) as cost_hs
from pointage_full pf, salarie s, hs_increase hsi
where s.id = pf.id_salarie
and hsi.etat = 1
and id_chantier = ?
and id_salarie <> id_chef
group by id_salarie, np, hour_salary, id_activity, id_chantier, value_update
) as recap
group by id_activity
order by id_activity asc;
You should also use a PreparedStatement instead of concatenating parameters into your SQL. If you have the above query in a String, you can do something like this:
PreparedStatement pstmt = connection.prepareStatement(QUERY);
pstmt.setInt(1, this.idProject);
ResultSet rs = pstmt.executeQuery();
while (rs.next()
{
// process result set
}
I'm pretty sure this will be faster than first creating a temp view and then querying that.

Copy values from one table to another with 'where' condition

I want to copy values from songDetails table to playlistDetails table.
here is my code :
public void transferData(String name) {
SQLiteDatabase db = this.getWritableDatabase();
String selectQuery = "INSERT INTO "+ TABLE_CURRENTLIST + " SELECT * FROM " + TABLE_DATA + " WHERE " + KEY_ALBUMNAME+ " = " + name + "";
db.execSQL(selectQuery);
}
While executing this code, it throws this exception
01-31 01:29:49.426: E/AndroidRuntime(3102): android.database.sqlite.SQLiteException: no such column: unknown (code 1): , while compiling: INSERT INTO PlayListDetails SELECT * FROM songDetails WHERE albumName = unknown
the value of 'name' variable is correct. And i want to copy only the rows which have the albumName as unknown.
I'm struggled with this. Please help me.
You are missing single quotes around query param value (unknown).
Your query should be
String selectQuery = "INSERT INTO "+ TABLE_CURRENTLIST + " SELECT * FROM " + TABLE_DATA + " WHERE " + KEY_ALBUMNAME+ " = '" + name + "'";
My suggestion would be to use PreparedStatement style parameters.

Using '%' as a wild card character in a parameter in SQL with Java

So in my program I have:
private static final String GET_USERS_BY_PARAMS = "select * from user t "
+ "where t.id like %?% "
+ "AND t.name LIKE %?% "
+ "AND t.location LIKE %?% "
+ "AND t.telephone LIKE %?% ";
All of the parameters given above are stored as varchar in the database.
However when I run the following:
statement = connection.prepareStatement(GET_USERS_BY_SEARCH_PARAMS);
statement.setString(1, userID);
statement.setString(2, name);
statement.setString(3, location);
statement.setString(4, telephone());
rs = statement.executeQuery();
I get a SQL exception stating that there was an invalid character. The application throws the error on the executeQuery, so setting the params isn't an issue. I was wondering if this was down to using the % symbols, whihc I included so that you could search without having to input the exact user ID, name, or etc.
Thanks for any help in advance!
The wildcard has to be part of the value passed to the prepared statement. So you need something like this:
private static final String GET_USERS_BY_PARAMS = "select * from user t "
+ "where t.id like ? "
+ "AND t.name LIKE ? "
+ "AND t.location LIKE ? "
+ "AND t.telephone LIKE ? ";
statement = connection.prepareStatement(GET_USERS_BY_SEARCH_PARAMS);
statement.setString(1, "%" + userID + "%");
statement.setString(2, "%" + name + "%");
statement.setString(3, "%" + location + "%");
statement.setString(4, "%" + telephone() + "%");
Btw: what datatype is user.id?
If that is a numeric value, LIKE won't work correctly. You should probably explictely cast the ID to a character value instead: where to_char(t.id) like ?
use CONCAT function,it will works,like this: LIKE CONCAT('%', ?, '%')
or also you can use LIKE ('%' || ? || '%')
You can write with concatenation operator
LIKE ('%' || ? || '%')

Categories