Can't figure out why SQL statement isn't woking - java

I can't understand what's wrong with my statement. Seems right to me, and the cursor should include both rows in my database table. According to SQLite website this formatted date is supported (Also tried with other supported dates).
String statement = "SELECT * FROM " + TABLE_DISTANCE_NAME + " WHERE " + COLUMN_TIME_DISTANCE_ADDED + " BETWEEN " + "2014-07-14" + " AND " + "2014-08-14";
Log.d("statement", statement);
Cursor cur = db.rawQuery(statement, null);
Log.d("cursor amount rows", Integer.toString(cur.getCount()));
if (cur != null) {
cur.moveToFirst();
}
int totalDistance = 0;
while (cur.isAfterLast() == false) {
Log.d("cursor distance value", Integer.toString(cur.getInt(0)));
totalDistance += cur.getInt(0);
cur.moveToNext();
}
Log.d("Total Distance traveled = ", Integer.toString(totalDistance));
This is what the table looks like.
Log:
...statement﹕ SELECT * FROM distanceTraveled WHERE timedistadded BETWEEN 2014-07-14 AND 2014-08-14
com.example.RoadTrip D/cursor amount rows﹕ 0
com.example.RoadTrip D/Total Distance traveled =﹕ 0
Thank you

Date constants need to be enclosed in single quotes:
" WHERE " + COLUMN_TIME_DISTANCE_ADDED + " BETWEEN " + "'2014-07-14'" + " AND " + "'2014-08-14'";
This problem would be more readily apparent if you printed out the SQL statement after the substitution. That is always a good first step in trying to debug this type of problem.

try quoting you query paramaters
e.g.
+ "'2014-07-14'" + " AND " + "'2014-08-14'"
Dates and Strings need to be single quoted as per SQL.

Related

How can I use window aggregation on temporary view generated by 3 Kafka topics joining using Flink-SQL?

Here is my requirements, there are 3 Kafka topics:
topic1-device & topic2-consumer & topic3-order.
we are going to calculate the order(amount) per device from the past 12hours using flink SQL.
I did the following things:
Regiter 3 tables corresponding 3 kafka topics.
// java code
String creConsumer = "CREATE TABLE " + consumerTable + " (" +
" deviceId STRING" +
",deviceFingerprintHash STRING" +
",consumer ROW(consumerUuid STRING)" +
",eventInfo ROW<eventTime BIGINT>" +
",id BIGINT" +
",ts AS TO_TIMESTAMP(FROM_UNIXTIME(eventInfo.eventTime/1000, 'yyyy-MM-dd HH:mm:ss'))" +
",WATERMARK FOR ts AS ts - INTERVAL '5' SECOND" +
") WITH (...)";
String createToken = "CREATE TABLE " + orderTokenTable + " (" +
"sessionId BIGINT" +
",token STRING" +
",eventInfo ROW(eventTime BIGINT)" +
",ts AS TO_TIMESTAMP(FROM_UNIXTIME(eventInfo.eventTime/1000, 'yyyy-MM-dd HH:mm:ss'))" +
",WATERMARK FOR ts AS ts - INTERVAL '5' SECOND" +
") WITH (...)";
String createTransaction = "CREATE TABLE " + orderTransactionTable + " (" +
"orderTransactionId BIGINT" +
",consumer ROW(`consumerUuid` STRING)" +
",token STRING" +
",countryCode STRING" +
",consumerTotalAmount ROW<amount STRING>" +
",status STRING" +
",eventInfo ROW<eventTime BIGINT>" +
",ts AS TO_TIMESTAMP(FROM_UNIXTIME(eventInfo.eventTime/1000, 'yyyy-MM-dd HH:mm:ss'))" +
",WATERMARK FOR ts AS withOffset(ts,1000)" +
") WITH (...)";
Join the 3 tables and generate a View:
// java code
String createWideTable = "CREATE VIEW view_order_consumer AS " +
"SELECT " +
" otc.eventTime " +
",otc.orderTransactionId " +
",otc.token" +
",otc.consumerUuid " +
",otc.countryCode " +
",CAST(otc.amount AS DOUBLE) AS amount " +
",otc.status " +
",csc.deviceId " +
",csc.deviceFingerprintHash " +
",otc.ts " +
"FROM " +
" order_transaction_completed otc " +
"INNER JOIN order_token_added ota " +
" ON (otc.token=ota.token AND otc.ts BETWEEN ota.ts - INTERVAL '10' DAY AND ota.ts + INTERVAL '10' DAY)" +
"INNER JOIN consumer_session_created csc " +
" ON (ota.sessionId=csc.id AND csc.ts BETWEEN otc.ts - INTERVAL '10' DAY AND otc.ts) ";
Do the aggregation job using window agg(Hop Window):
// SQL
select deviceId
,HOP_START(voc.ts, INTERVAL '5' SECOND , INTERVAL '10' SECOND)
,count(1) as cnt
from consumer_session_created as voc
group by HOP(voc.ts, INTERVAL '5' SECOND , INTERVAL '10' SECOND)
,deviceId
Output result table data:
// java
DataStream<Tuple2<Boolean, Row>> retractResultStream = tableEnvironment
.toRetractStream(table, Row.class);
retractResultStream.print();
However I can't get any result(No error messages).
Change the sql to :
// SQL
select * from view_order_consumer
Result:
6> (true,1628564685939,100100113280,002.qa2dtem5k6umlokop1boud4c8p77c9lhclb8i5ug0na383ed,94e44b95-223b-4479-82b9-b4f710f7f8c3,US,10.0,APPROVED,740baadd20e544e8bdcdc8d2a76cbdc9,c718225f5f1d4876ffc1ce2bb5ab3852,2021-08-10T11:04:45)
6> (true,1628564687358,100100113280,002.qa2dtem5k6umlokop1boud4c8p77c9lhclb8i5ug0na383ed,94e44b95-223b-4479-82b9-b4f710f7f8c3,US,11.0,APPROVED,740baadd20e544e8bdcdc8d2a76cbdc9,c718225f5f1d4876ffc1ce2bb5ab3852,2021-08-10T11:04:47)
6> (true,1628564688364,100100113280,002.qa2dtem5k6umlokop1boud4c8p77c9lhclb8i5ug0na383ed,94e44b95-223b-4479-82b9-b4f710f7f8c3,US,12.0,APPROVED,740baadd20e544e8bdcdc8d2a76cbdc9,c718225f5f1d4876ffc1ce2bb5ab3852,2021-08-10T11:04:48)
After some research, I found that the time-attr will be dropped after join operator in Flink.
Can anyone tell me how can I get the correct data using FLink-sql ?
I'm not sure what's wrong, but here are some ideas:
FWIW, it's easier to iterate and debug these situations using an interactive tool, such as the SQL client that ships with Flink, or the one built into Ververica Platform.
You can use "explain ..." to see the plan that has been produced for the query. This often provides some clues.
I'm not sure what to expect from WATERMARK FOR ts AS withOffset(ts,1000). Are you sure that works? In most cases where a Flink job or SQL query produces no results, the cause turns out to be a problem with the watermarking.
I would try tearing apart the 3-way join, and instead do a sequence of two joins. That may produce a different plan; possibly one that works better.

Spring Data JPA: native summary gets ConverterNotFoundException

Update
I've changed the first method to return a List, but I get the same exception.
I have 2 native queries in my Repository class. One is typed to return all records, the other returns just one row. See below:
#Query(nativeQuery = true, value = NATIVE_SUMMARY_QUERY_PARTIAL + "group by (rjd.refresh_job_identifier)) as rc")
List<RefreshSummary> getRefreshJobDetailSummary();
#Query(nativeQuery = true, value = NATIVE_SUMMARY_QUERY_PARTIAL + " WHERE rjd.refresh_job_identifier = :refreshJobId" +
" group by (rjd.refresh_job_identifier)) as rc")
List<RefreshSummary> getRefreshJobDetailSummaryById(#Param("refreshJobId") String refreshJobId);
interface RefreshSummary {
String getRefreshJobId();
Date getRefreshJobStart();
Date getRefreshJobComplete();
String getUserId();
long getTotalRecords();
long getSuccessfulRecords();
long getPendingRecords();
long getErrorRecords();
long getCancelledRecords();
String getRefreshJobStatus();
}
String NATIVE_SUMMARY_QUERY_PARTIAL = "SELECT rc.refresh_job_identifier as refresh_job_id, ..."
The first method, getRefreshJobDetailSummary, works fine. But the second method, where I want only one row, gives me this exception:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [com.company.repository.RefreshJobDetailRepository$RefreshSummary]
The full query looks like this:
String NATIVE_SUMMARY_QUERY_PARTIAL = "SELECT rc.refresh_job_identifier as refresh_job_id, " +
"rc.refresh_job_start_time as refresh_job_start, " +
"rc.record_completion_time as refresh_job_complete, " +
"rc.user_id as user_id, " +
"rc.pending + rc.successful + rc.cancelled + rc.error as total_records, " +
"rc.successful as successful_records, " +
"rc.pending as pending_records, " +
"rc.error as error_records, " +
"rc.cancelled as cancelled_records, " +
"CASE WHEN pending > 0 THEN 'In progress' " +
"ELSE 'Complete' " +
"END as refresh_job_status " +
"FROM " +
"(SELECT rjd.refresh_job_identifier as refresh_job_identifier, " +
"MAX(rjd.refresh_job_start_time) as refresh_job_start_time, " +
"MAX(rjd.record_completion_time) as record_completion_time, " +
"MAX(rjd.org_usr_nu) as user_id, " +
"SUM(CASE WHEN LOWER(record_status) = 'pending' THEN 1 ELSE 0 END) as pending, " +
"SUM(CASE WHEN LOWER(record_status) = 'successful' THEN 1 ELSE 0 END) as successful, " +
"SUM(CASE WHEN LOWER(record_status) = 'cancelled' THEN 1 ELSE 0 END) as cancelled, " +
"SUM(CASE WHEN LOWER(record_status) = 'error' THEN 1 ELSE 0 END) as error " +
"from erd_cfg_owner.refresh_job_detail rjd " ;
And the value the query returns looks like this:
'{20191218204913458hc35, 2019-12-18 20:49:13.314, 2019-12-18 20:49:24.335, hc35, 1, 1, 0, 0, 0, Complete}'
Can someone shed any light on this? Why would one method work but not the other?
I would replace the return type of your 2nd method from RefreshSummary to List<RefreshSummary>. In theory your method is supposed to return a list not a single value
Could you try using constructor expression in query declaration or by creating custom converter.
Eg-SELECT NEW com.example.MyClass(e.attribute1, e.attribute2...) FROM MyEntity e");

how to pass positional parameters to createnativequery jpa java

I have the following SQL query in my j2ee web app that I am unable to get to work, as-is. The named parameters sourceSystem and sourceClientId do not appear to get passed to the query, and therefore it does not return any records. I added a watch to the Query object querySingleView and it maintained a value of null as the debugger ran through the code. I also inserted a System.out.println statement just under the method declaration and confirmed that the correct values sourceSystem and sourceClientId are being passed to the method signature. I am using NetBeans 8.0, JPA 2.1, running on a JBoss EAP 6.21 server. I have multiple Entities mapped to several tables in an Oracle database.
Here is the query (I should note that the items in the query follow a schema.table.column format - not sure if that is part of the problem, but it does work in one test, see my comment and sample below the main query below):
public List<String> searchSingleView (String sourceSystem, String sourceClientId) {
//Change the underscore character in the source system value to a dash, and make it uppercase. This is what single view accepts
if (!sourceSystem.equals("")) {
sourceSystemSingleView = sourceSystem.replace('_', '-').toUpperCase();
}
String sqlSingleViewQuery = "SELECT DISTINCT " +
"MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM AS POLICY_SYSTEM, " +
"MDMCUST_ORS.C_BO_CONTRACT.SRC_POLICY_ID AS POLICY_ID, " +
"MDMCUST_ORS.C_BO_CONTRACT.ISSUE_DT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID AS SRC_CLIENT_ID, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.PERS_FULL_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_LEGAL_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_LEGAL_SFX_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.SIN_BIN_TEXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.PERS_BIRTH_DT, " +
"MDMCUST_ORS.C_LU_CODES.CODE_DESCR_EN AS ADDRESS_PURPOSE_CD, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.COMPLETE_ADDRESS_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.CITY_NAME, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.COUNTRY_NAME, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_CD, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.STATE_PROVINCE_NAME " +
"FROM MDMCUST_ORS.C_BO_PARTY_XREF " +
"LEFT JOIN MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR ON MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.PARTY_ROWID = MDMCUST_ORS.C_BO_PARTY_XREF.ROWID_OBJECT " +
"LEFT JOIN MDMCUST_ORS.C_LU_CODES ON MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_ADDR_PURPOSE_CD = MDMCUST_ORS.C_LU_CODES.CODE " +
"LEFT JOIN MDMCUST_ORS.C_BO_PARTY_REL ON MDMCUST_ORS.C_BO_PARTY_XREF.ROWID_OBJECT = MDMCUST_ORS.C_BO_PARTY_REL.FROM_PARTY_ROWID " +
"LEFT JOIN MDMCUST_ORS.C_BO_CONTRACT ON MDMCUST_ORS.C_BO_PARTY_REL.CONTRACT_ROWID = MDMCUST_ORS.C_BO_CONTRACT.ROWID_OBJECT " +
"WHERE MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM = :sourceSystemSingleView " +
"AND MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID = :sourceClientId " +
"AND MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_ADDR_PURPOSE_CD = '56|07' " +
"AND MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.LAST_ROWID_SYSTEM = MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM " +
"ORDER BY MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM";
querySingleView = emSingleView.createQuery(sqlSingleViewQuery);
querySingleView.setParameter("sourceSystemSingleView", sourceSystemSingleView);
querySingleView.setParameter("sourceClientId", sourceClientId);
querySingleViewResult = (List<String>) querySingleView.getResultList();
return querySingleViewResult;
}
}
However, if I put literal values in the SQL query in place of the positional parameters it works fine (without using the setParameter method).
WHERE MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM = 'ADMIN' " +
"AND MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID = '0000001234' " +
I have looked online but haven't as yet found anything that seems to address this specific question. Any help would be greatly appreciated. Thank you!

Derby db stating that column does not exist when it does

Ok so I have an application that connects to a database that has a customer table. In the customer table I capture a range of different values. VH_ID is a foreign key to the vehicle table and the insurance_ID is also a foreign key to the insurance table.
Any ideas would be appreciated.
Edit
public CustomerInformation getCustomerInfo(String customerName) {
CustomerInformation info = new CustomerInformation();
ResultSet result;
try {
String sqlStatement = "SELECT "
+ DBStrings.C_NAME + ","
+ DBStrings.C_ADDRESS + ","
+ DBStrings.C_PHONENO + ","
+ DBStrings.C_EMAIL + ","
+ DBStrings.C_VH_ID + ","
+ DBStrings.C_VH_MODEL + ","
+ DBStrings.C_VH_YEAR + ","
+ DBStrings.C_VH_REGO + ","
+ DBStrings.C_VH_CHASSIS + ","
+ DBStrings.C_VH_VIN + ","
+ DBStrings.C_INSURANCE
+ " FROM " + DBStrings.CUSTOMER + " WHERE " + DBStrings.C_ID + " = " + this.getCustomerId(customerName);
result = statement.executeQuery(sqlStatement);
while (result != null && result.next()) {
info.setName(result.getString(DBStrings.C_NAME));
info.setAddress(result.getString(DBStrings.C_ADDRESS));
info.setPhoneNumber(result.getString(DBStrings.C_PHONENO));
info.setEmail(result.getString(DBStrings.C_EMAIL));
info.setRego(result.getString(DBStrings.C_VH_REGO) + "");
info.setChassis(result.getString(DBStrings.C_VH_CHASSIS) + "");
info.setVin(result.getString(DBStrings.C_VH_VIN) + "");
info.setVehicleModel(result.getString(DBStrings.C_VH_MODEL) + "");
info.setYear(result.getInt(DBStrings.C_VH_YEAR) + "");
info.setInsurance(this.getInsuranceFromId(result.getInt(DBStrings.C_INSURANCE)));
info.setVehicleMake(this.getVehicleFromId(result.getInt(DBStrings.C_VH_ID)));
}
} catch (SQLException ex) {
Logger.getLogger(Database.class
.getName()).log(Level.SEVERE, null, ex);
}
return info;
}
That is the new code with the ResultSet nested inside the method. Now I am getting the error:
SEVERE: null
java.sql.SQLException: ResultSet not open. Operation 'getInt' not permitted. Verify that autocommit is OFF.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.ResultSet.getInt(Unknown Source)
at Database.Database.getCustomerInfo(Database.java:599)
Statement
connection = DriverManager.getConnection(connectionURL, "user", "pass");
statement = connection.createStatement();
Maybe you have column VH_MODEL twice in your query due to a "copy-paste accident" in the constants, i.e. another constant also expands to "VH_MODEL", specifically one of the columns following VH_MODEL in the get sequence. The DBMS would rename the result columns to make them unique in this case I guess. This would explain the strange situation where excuteQuery works while the getString fails.
Essentially the work around that I did to solve this issue was to create another method just specifically for retrieving the vehicle make. Seems a bit pointless but for the life of me I have no idea why it is not accepting it. The method has exactly the same contents for retrieving the data as in the first method.. Seems very odd.
String sqlStatement = "SELECT "
+ DBStrings.C_VH_ID
+ " FROM " + DBStrings.CUSTOMER + " WHERE " + DBStrings.C_ID + " = " + customerId;
rs = statement.executeQuery(sqlStatement);
if (rs != null && rs.next()) {
int vh_id = rs.getInt(DBStrings.C_VH_ID);
vehicle = this.getVehicleFromId(vh_id);
}

MySql Data truncated for column 'advance' at row 1

In my project I used txtAdvance 's key event.
double gtotal = Double.parseDouble(txtGtotal.getText());
double ad = Double.parseDouble(txtAdvance.getText());
double due = gtotal - ad;
txtDue.setText(String.valueOf(due));
And after last line run, I add a save button to save those data. Given below is that query.
public void saveInvoice(JTextField txtgtotal, JTextField txtAdvance, JTextField txtDue, JTextField txtInID) {
try {
db.putData("INSERT INTO indetails(inid, gtotal, advance, due) VALUES( '" + txtInID.getText() + "' ,'" + txtgtotal.getText() + "' , '" + txtAdvance.getText() + " ' " + " , '" + txtDue.getText() + "') ");
JOptionPane.showMessageDialog(null, txtAdvance.getText());
JOptionPane.showMessageDialog(null, "Invoice details saved");
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, this.getClass().getName() + " first " + e);
}
}
I'm having MySql Data truncated for column 'advance' at row 1 . advance's data type is Double. But I can't find a way to put length.
(As an example
Column Name : iid, Data type : Int(18) {Primary key}
Column Name : inid, Data type : Int(18)
Column Name : gtotal, Data type : Double
Column Name : advance, Data type : Double
Column Name : due, Data type : Double
)
I'm using MySQL query browser . Question is when I'm adding 0 value to txtAdvance I'm having this error.
If the data you are trying to save have decimal points then change the datatype for advance as double with length 10,3 where 10 denotes number of digits and 3 denotes the number of decimal digits.
Use this query,
db.putData("INSERT INTO indetails(inid, gtotal, advance, due) VALUES(" + txtInID.getText() + "," + txtgtotal.getText() + "," + txtAdvance.getText() + "," + txtDue.getText()+")");
Instead of creating your query by hand, you should use db driver for it:
PreparedStatement putData = con.prepareStatement("INSERT INTO indetails(inid, gtotal, advance, due) VALUES(?,?,?,?)");
double gtotal = Double.parseDouble(txtGtotal.getText());
double ad = Double.parseDouble(txtAdvance.getText());
double due = gtotal - ad;
putData.setInt(1, inid);
putData.setDouble(2, gtotal);
putData.setDouble(3, ad);
putData.setDouble(4, due);
try {
putData.execute();
JOptionPane.showMessageDialog(null, txtAdvance.getText());
JOptionPane.showMessageDialog(null, "Invoice details saved");
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, this.getClass().getName() + " first " + e);
}

Categories