Using Store Procedure with multiple result JPA - java

I have two tables in SQL Server :
Table A
ID Num
11 tj55
4 tj40
Table B
ID NUM A_ID
3 se400 4
5 se500 4
I have a stored procedure which will return for each row in A all corresponding rows in B, I have this result
NumA NumB
tj40 se400
tj40 se500
Code:
ALTER PROCEDURE [dbo].[Proc]
#param nvarchar(MAX),
AS
BEGIN
SELECT
aa.Num,
bb.Num
FROM
[dbo].[A] as aa
INNER JOIN
[dbo].[B] AS bb ON bb.A_ID = aa.ID
WHERE
aa.Num = #param
ORDER BY
aa.Num
END
I want to use a call my StoredProcedure in my Java application with JPA to have the two rows generated (my goal is to have List containing all the NumB (in this case 'se400' and 'se500')
StoredProcedureQuery query2 = em.createStoredProcedureQuery("Proc");
query2.registerStoredProcedureParameter("param", String.class,ParameterMode.IN);;
query2.setParameter("param", "tj40");
query2.execute();
List<Object> res = query2.getResultList();
for (int i=0; i<res.size(); i++){
System.out.println(res.get(i).toString());
}
it founds the two rows but it returns
[Ljava.lang.Object;#94814
[Ljava.lang.Object;#00856
Could you help me please?
Thank you very much

In my application I am using the following way
List i1 = query2.getResultList();
while(i1.hasNext()){
Object[] object =(Object[]) i1.next();
//your rest code
//object[0] will contain numA and object[1] will contain numB
}

Related

Generate Dynamic Query using JOOQ

I want to generate a SQL query where tables name is stored in the tables array.
and the corresponding columns name stored in a 2-D array.
example:-
Tables array
[T1,T2,T3]
Columns array
[
[C1,C2], // T1 columns
[C1,C2], // T2 columns
[C1,C2] // T3 columns
]
QUERY:-
select T1.C1,T2.C1,T3.C1 from T1
inner join T2 ON T2.C2=T1.C2;
inner join T3 ON T3.C2=T1.C2
select first column of every table in the array
if they have a match in the second column
[assuming every table has 2 columns]
I don't want to execute this query.
I just want to print it using JOOQ.
Can someone pls help me out on this.
The phrasing of your question gives room to some interpretation. I'm assuming you have these specific array types:
Table<?>[] tables = ...
Field<?>[][] fields = ...
I'm assuming that your requirement is to match all tables by common column names (i.e. names that are the same as the name of the second column of the first table), in order to join them. Since you do not specify what happens if consecutive tables don't have such a match, I'm assuming you'd like to default to excluding such tables, and their columns.
In any case, I guess this is more of a question about an idea on how to do dynamic SQL with jOOQ in general, not necessarily how to solve your particular problem.
In that case, write:
Field<?> match = fields[0][1];
List<Field<?>> select = new ArrayList<>();
Table<?> from = tables[0];
select.add(fields[0][0]);
for (int i = 1; i < fields.length && i < tables.length; i++) {
if (match.getName().equals(fields[i][1].getName())) {
select.add(fields[i][0]);
from = from.join(tables[i]).on(match.eq((Field) fields[i][1]));
}
}
ctx.select(select)
.from(from)
.fetch();
If your actual requirements are very different to these assumptions, you can still ask a new question.

Parent-Child Relational Table

Context:
A table of transactions coming from an external system is queried to create elements on a local system with two main columns:
A child that is not yet persisted in the local database
Possible multiple parents semi-colon separated (which can be persisted locally or not yet created)
I'm having a problem with sorting a table that looks like this:
Child Parents
A B;C
B C;E
C F;X
What I want to accomplish is to make sure the Parent always gets created before the child:
Child Parents
C F;X
B C;E
A B;C
F, X & E in this example represents elements already persisted in the local database that could be on my query
I spent some time thinking this through and it seems it's related to trees / graphs on which I have little to no knowledge...
Any idea what kind of sorting we are dealing with here and possible java or SQL implementations?
Edit:
Every Child Element is an element that is not persisted yet on the database
A child can either have a list of parents already persisted (like F, X & E) or parents I still need to persist (in which case they need to precede said child) or a mix of both (like B with C;E parents E already persisted and C comes in this transaction and must precede B)
Can not alter the database, but can reorder things freely in java
Thanks in advance
Partial Solution
I've adapted Joshua's solution and it seems to work this way:
(basically use like statement because we can have something like AA;BB;CC as a parent)
SELECT DISTINCT
s1.child,
s1.parents,
CASE
WHEN s2.parents IS NULL THEN 0
WHEN s2.parents LIKE '%' + s1.child + '%' THEN 1
ELSE 3
END
AS x
FROM
sample s1
LEFT JOIN sample s2 ON s2.parents LIKE '%' + s1.child + '%'
WHERE
s1.treateddate IS NULL
ORDER BY
CASE
WHEN s2.parents IS NULL THEN 0
WHEN s2.parents LIKE '%' + s1.child + '%' THEN 1
ELSE 3
END
DESC
This solution doesn't account for a child which is a parent at the same time!
Solution Java
I found the solution in Java to reordering the dataset, this is just pseudo code because I'm using a proprietary library...
private void sortByParentFirst(rows) {
for (int i = 0; i < rows.size(); i++) {
for (int j = 0; j < rows.size(); j++) {
boolean match = false;
//parents comma seperated at j contain child i
if (Parents[j].contains(Child[i]) ) {
match = true;
}
//this means we found an occurrence of the child i at a previous position j
if (match && j < i) {
//swap rows i & j
swap(i,j);
break;
}
}
}
}
Here the table sample contains your data
select * from sample
chid parents
---- ----------
A B;C
B C;E
C F;X
select * from sample
drop table #sample
drop table #sample2
select * into #sample from sample
select * into #sample2 from sample where 1=2
alter table #sample2 add counter int
declare #count int
select #count = count(1) from #sample
declare #child char(1)
declare #counter int = 1
while(#count > 0)
begin
select #child = t1.chid
from #sample t1
inner join #sample t2 on CHARINDEX(t1.chid,t2.parents) = 0
group by t1.chid
having count( t1.chid) = 1
insert into #sample2
select *,#counter from #sample where chid = #child
delete from #sample where chid = #child
select #count = count(1) from #sample
set #counter = #counter + 1
end
select chid, parents from #sample2 order by counter
select distinct s1.* ,
case when s2.parents is null and s3.parents is null then 0
when s1.child = left(s2.parents,1) and s3.parents is null then 1
when s1.child = right(s3.parents,1) and s2.parents is null then 2
else 3 end as x
from sample s1
left join sample s2 on s1.child = left(s2.parents,1)
left join sample s3 on s1.child = right(s3.parents,1)
order by
case when s2.parents is null and s3.parents is null then 0
when s1.child = left(s2.parents,1) and s3.parents is null then 1
when s1.child = right(s3.parents,1) and s2.parents is null then 2
else 3 end desc
SQL Fiddle Example
Join the table back to itself twice looking for a match to a parent. If the real date is more than just a character, then you can use CHARINDEX to locate the delimiter and per form a left or right based off the location of the returned starting position.

How implement friends Relationship android

I'm trying to implement some code for get friends list.
First:
- I have my String id. E.G: 784717
- I have an string with 100 numbers. E.G: 7781,5913,551949194,4919491,...,444131 (One string separated by ,)
- I have 3000 records in my Database with different numbers. (With numbers I mean some kind of ID)
- Of my 100 numbers only 8 are registered in my database.
Question:
How can I know what numbers are registered in the database and insert in other table the relationship?
My table Relationship have this columns:
*number1 - (Here should be my ID)
*number2 - (1 of the 100 numbers that exists)
So in my table Relationship should be 8 new rows.
I tried with :
EXEC('SELECT * FROM Accounts WHERE ID IN(' +#in_mystring+')')
but i don't know how insert in the other table or if is efficiently
Assuming this is SQL Server, and with the help of a parser function
For example
Select * from [dbo].[udf-Str-Parse]('7781,5913,551949194,4919491,...,444131',',')
Returns
Key_PS Key_Value
1 7781
2 5913
3 551949194
4 4919491
5 ...
6 444131
From this sub-query, you can join the results to your Accounts Table
Perhaps something like this
Select A.*
From Accounts A
Join (Select * from [dbo].[udf-Str-Parse]('7781,5913,551949194,4919491,...,444131',',')) B
on A.Key_Value =A.ID
The UDF -- If 2016, There is a native parser.
CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
-- Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
-- Select * from [dbo].[udf-Str-Parse]('id26,id46|id658,id967','|')
Returns #ReturnTable Table (Key_PS int IDENTITY(1,1) NOT NULL , Key_Value varchar(max))
As
Begin
Declare #intPos int,#SubStr varchar(max)
Set #IntPos = CharIndex(#delimeter, #String)
Set #String = Replace(#String,#delimeter+#delimeter,#delimeter)
While #IntPos > 0
Begin
Set #SubStr = Substring(#String, 0, #IntPos)
Insert into #ReturnTable (Key_Value) values (#SubStr)
Set #String = Replace(#String, #SubStr + #delimeter, '')
Set #IntPos = CharIndex(#delimeter, #String)
End
Insert into #ReturnTable (Key_Value) values (#String)
Return
End

Hibernate Criteria API: how to get the sum of all the values along two columns

the question is very simple but I cannot get something working.
Say, I have the following table
|....X....|.....A.....|.....B....|
|...........|.....3.....|.....2.....|
|...........|.....1.....|.....4.....|
|...........|.....1.....|.....2.....|
I simply have to obtain the total sum of values in column A and B, so (3 + 1 + 1) + (2 + 4 + 2) = 13 and I'd like to have it with Criteria API.
I tried creating a Projection summing the values along A and a DetachedCriteriawith a similar Projection summing the values along B, but I couldn't obtain a unique result from the DetachedCriteria since it doesn't expose this method.
Any advice?
You can do that with sqlProjection
.setProjection(Projections.sqlProjection("sum(A + B) as sumAB", new String[] {"sumAB"} , new Type[] {Hibernate.DOUBLE}));
https://stackoverflow.com/a/21650037/351861
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Number> q = cb.createQuery(MyEntity.class);
Root<MyEntity> t = q.from(MyEntity.class);
Path<Number> fieldB = t.get(MyEntity_.B);
Path<Number> fieldA = t.get(MyEntity_.A);
Expression<Number> sum = cb.sum(fieldA, fieldB);
q.select(sum.alias("SUM"));
System.out.println(em.createQuery(q).getSingleResult());

how to sort a column of a table in database with hibernate

I want to find 10 nearset value of a column of a table in a database to my value.
so I want to sort the value of that column, and then find 10 smaller or bigger value than my value.
how can I do this
thanks a lot for your help
HQL supports ORDER BY.
Either you do
Query q = session.createQuery("from Table order by abs(value - :v) asc";
q.setXxx("v", myValue); /* Xxx is Float or Long or Integer or... */
q.setMaxResults(10);
List<Table> l = q.list();
or
Query q1 = session.createQuery("from Table where value >= :v order by value asc";
q1.setXxx("v", myValue); /* Xxx is Float or Long or Integer or... */
q1.setMaxResults(10);
List<Table> l1 = q1.list();
Query q2 = session.createQuery("from Table where value < :v order by value desc";
q2.setXxx("v", myValue); /* Xxx is Float or Long or Integer or... */
q2.setMaxResults(10);
List<Table> l2 = q2.list();
/* now find the 10 nearest elements in Java code */
...
while (...) {
...
}
In the second example you have the inconvenience of two selects which give you 20 rows altogether and then you have to find the 10 nearest in Java code, but if there is a database index on the value column it might b a lot faster. The result will be the same for both examples.

Categories