Quarkus Hibernate/Panache NativeQuery with Multiple Row Inserts - java

I'm trying to create some type of update endpoint that when you hit it does an insert from one table to another table. Basically it takes from a table named funds which was fundId, reportingfrequency and country. IT retains the fundIds and for the value it gets a List of Dates that are a result of a join with a Postgres stored procedure/function. Here is an example of the SQL query in it's entirety. So ideally if there are 100 rows in the table it would insert all 100 rows with an array of dates into the due_dates table.
INSERT INTO due_dates (fund_id, listdate)
SELECT fundid,
(
SELECT array_agg(weekdays::date)
FROM generate_series(date'2021-01-01', date'2021-12-31', interval '1' day) as t(weekdays)
LEFT JOIN holidays.poland(2021, 2021) f ON (weekdays = f.datestamp)
WHERE f.datestamp IS NULL
AND extract(dow from weekdays) BETWEEN 1 AND 5
)
FROM funds
WHERE reportingfrequency = 'Daily';
Now my issue is I'm not sure how to... programmatically do this so that depending on the rows from the funds table... I'm not sure how to grab the country field from the row to do a specific stored procedure call. For instance if a single row has Poland in it's country field then it would ideally call holidays.poland(2021, 2021)... and if the country was USA it would call holidays.usa(2021, 2021). Here's how my current NativeQuery.
entityManager.createNativeQuery("INSERT INTO due_dates (fund_id, listdate)" +
"SELECT fundid," +
"(" +
"SELECT array_agg(weekdays::date)" +
"FROM generate_series(date'2021-01-01', date'2021-12-31', interval '1' day) as t(weekdays)" +
"LEFT JOIN holidays." + country + "(" + year + "," + year + ") f ON (weekdays = f.datestamp)" +
"WHERE f.datestamp IS NULL" +
"AND extract(dow from weekdays) BETWEEN 1 AND 5" +
")" +
"FROM funds" +
"WHERE reportingfrequency = 'Daily'; ")
.executeUpdate();
Is there something I need to do to tweak the original SQL statement before I can achieve what I want to do?

Related

JPQL Constructor execution takes long time

I am using JPQL constructor in my code. It involves large results, 5024 data retrieved and objects created when executing this query. It is taking around 2 minutes to complete its execution. There are multiple tables involved to execute this query. I could not go for cache since the DB data will update daily. Is there any way to optimize the execution speed?
My SQL query formation is like this,
String sql = "SELECT DISTINCT "
+ "new com.abc.dc.entity.market.LaptopData(vd.segment.id, vd.segment.segmentGroup, "
+ "vd.segment.segmentName, vd.segment.category, "
+ "vd.product.make, vd.product.model, vd.product.modelYear) "
+ "FROM LaptopData vd, Profile p "
+ "WHERE vd.profile.profileCode = :profileCode "
+ "AND vd.pk.profileId = p.id "
+ "Order By vd.segment.segmentGroup, vd.segment.segmentName, vd.product.make, vd.product.model,"
+ " vd.product.modelYear asc";
Query query = em.createQuery(sql);
query.setParameter("profileCode", profileCode);
#SuppressWarnings("unchecked")
List<LaptopData> results = query.getResultList();
em.clear();
return results;
Well, one option for you is to create separate table which would contain result of this query for all entities and update it daily (every night) and then run your query on this new table, like this:
"SELECT DISTINCT"
+ "new com.abc.dc.entity.market.LaptopData(m.id, m.segmentGroup, "
+ "m.segmentName, m.category, "
+ "m.make, m.model, m.modelYear) "
+ "FROM someNewTable m"
+ "WHERE m.profileCode = :profileCode ";
This way you don't have to do join and ordering every time you execute your query, but only once a day when you generate new table. Ofcourse with this approach to see data updates you'll have to wait until new table is recreated.
Also, you can create indexes on fields you are using in where clause.

SQL Insert Into a newly created column ,data placed after the last row of the previous column

I have a problem with a SQL statement. I have a java app with a button to add a column into a database. For every new date, I have a new column created, which is done using the following query
final String queryCreate = "alter table Currency add '"+ newColumn + "' decimal ";
When I try to populate the column with data using the following query:
final String queryAdd = "insert into Currency( '" + newColumn + "' ) values(1.95583)";
The data is added below the last row of the previous column.
like this:
https://postimg.org/image/579gjmyzj/
My question is why the insert statement does what it does in my situation, what am I doing wrong?
INSERT creates new records, if you want to modify existing records you need to use UPDATE.
For example, to modify the first record:
"UPDATE Currency SET " + newColumn + " = 1.95583 WHERE Currency_ID = 1"
use update query
assuming strCurrencyID="1";
strCurrencyName="EUR";
final String queryAddUpdate =
if exists(Select Top 1 1 from Currency where Currency_ID=" + strCurrencyID +")
Begin update Currency set " + newColumn + "=1.95583 where Currency_ID=" +strCurrencyID + "
End
Else
Begin
insert into Currency(Currency_id, Currency_name, '" + newColumn + "' ) values("+ strCurrencyID +",'" + strCurrencyName + ", 1.95583)
End"
This will update the value in in column if currency id exists if not this will insert new row.
But I think database design should be change can you explain your business requirement.

How to use inner join to get 'next column' value?

I've been researching for quite some time and it seems I may be misunderstanding how inner-joins work in MySQL.
I have 3 tables:
UserTable:
UserID UserName Hash UserUni UserHousing
1 John #123eq.. FK FK
2 Bob !S91ka.. FK FK
...
The foreign keys relate to the following two tables' PKs (UniID and HousingID, respectively):
UniversitiesList:
UniID UniName
1 Yale
2 Penn
...
HousingList:
HousingID HousingName UniID
1 Dorm_1 FK
2 Dorm_2 FK
...
Where, of course, these FKs are PKs (UniID) in Universities list
What I'm trying to do is query the id, hash, UserUni, and UserHousing values, i.e not the keys. This is what I'm playing around with now:
"SELECT UserTable.Hash, UserTable.UserID, UserTable.UserUni, UserTable.UserHousing "
+ "FROM UserTable "
+ "INNER JOIN UniversitiesList "
+ "ON UserTable.UserUni = UniversitiesList.UniID "
+ "INNER JOIN HousingList "
+ "ON UserTable.UserHousing = HousingList.HousingID "
+ "WHERE UserTable.UserName = John"
What I would like to retrieve is something like 1, #123eq, Yale, Dorm_1, but instead I keep getting 1, #123eq, 1, 1.
I'm working with Java so this is how I'm getting the results:
if (result.next()) {
hash = result.getString(1);
id = result.getInt(2);
uni = result.getString(3);
housing = result.getString(4);
}
Any idea one what I'm doing wrong?
Try changing your query to this:
"SELECT UserTable.Hash, UserTable.UserID, UniversitiesList.UniName, HousingList.HousingName "
+ "FROM UserTable "
+ "INNER JOIN UniversitiesList "
+ "ON UserTable.UserUni = UniversitiesList.UniID "
+ "INNER JOIN HousingList "
+ "ON UserTable.UserHousing = HousingList.HousingID "
+ "WHERE UserTable.UserName = John"
As written, you're only asking for the columns in your UserTable, not the other tables. The joins look ok from what I can tell...

Number of characters in sql query result

I am using Spring 3.1.1 with Hibernate 4 and a MSSQL database. Finally, I have been able to query my database with joins in my table that returns the correct answers. Although, it seems that it does not return the entire strings of my messages, but cuts at 29/30 digits. Here is my query:
SQLQuery sql = this.getCurrentSession().createSQLQuery(
"SELECT event.id as eventid, CAST(event_type.type_name AS varchar) as eventtype, event.check_date, event.event_date, event.status, CAST(event_message.message AS varchar) as eventmessage " +
"FROM event_log event " +
"LEFT JOIN event_type " +
"ON (event.event_type_id = event_type.id) " +
"LEFT JOIN event_message " +
"ON (event.event_message_id = event_message.id) " +
"WHERE event.event_type_id = " + jobId +
"ORDER BY eventid");
The result can be:
4506 Database 2014-01-15 14:14:15.02 2014-01-15 14:14:15.02 false Database-connection cannot be
Where the columns are id, task_name, check_date, event_date, status and the message-string at the end. .
The result goes to a ArrayList<Object[]> where I read row[0] etc. to get the entities in the row. The string message gets cut after 29 digits, which is disturbing. Why does it cut the string and how can I fix this? In my database the string exists in it's full and is entitled 400 characters max.
I know this is probably not the best way to query my database, but it will do for my application since it works.
You are using varchar without a length. Never do this!
Replace:
CAST(event_type.type_name AS varchar)
With something like:
CAST(event_type.type_name AS varchar(255))
In some contexts, the default length is 32. In some it is 1. In general, though, always specify the length.
EDIT:
Actually, you probably don't even need the cast. Why not just have event_type.type_name in the select list?

Formatting hql query

#My doubt is the partId in Product table can be null ,so if the partId is null I’m not able to see the product. If my Product Table has 11 entries and 2 entries have partId as null , Iam able to see only 9 entries
String hql = "from " + Product.class.getName() + " bs, "
+ Part.class.getName() + " dm, "
+ Manufacturer.class.getName() + " m where "
+ " m.id = bs.manufacturerId and dm.id = bs.partId ";
========================================
The ouput has to be like this
productName | PartName | Manufactuer Name
You need to do left joins instead of inner joins. But this is only possible if your entities are associated together instead of containing each other's IDs.
As is, it's plain impossible with HQL.
Given your query, you probably should have a ManyToOne between Product and Manufacturer, and a ManyToOne between Product and Part.
Also, your query would be much more readable if you didn't concatenate class names and if you used proper alias names:
String hql = "from Product product, Part part, Manufacturer manufacturer"
+ " where manufacturer.id = product.manufacturerId"
+ " and part.id = product.partId";
Once the associations exist, the query should just be
String hql = "select product.name, part.name, manufacturer.name"
+ " from Product product"
+ " left join product.part part"
+ " left join product.manufacturer manufacturer";

Categories

Resources