How to write large id's in SQL In ('','') format? - java

I have a method which returns record from a database based on a id's. Now I need to fetch records for 1000 records and I feel like it is not a good practice to write all id's in the in clause manually. Is there a tool where I paste the id's and it gives me like this id in ('123', '456', and so on)?
I can't write all the id's by my self manually.Business provides the id's in excel and they are very large in number. is there a way to accomplish this?
My method
#Override
public List<NYProgramTO> getLatestNYData() throws Exception {
String query = "SELECT REQ_XMl, SESSIONID, EXPIRATION_DATE, QUOTE_DATE, POLICY_EFFECTIVE_DATE, TARGET_CREATED, RATING_TRANSACTION_ID, SOURCE_LASTMODIFIED FROM dbo.XML_SESSIONS with (nolock) WHERE XML_SESSIONS.LOB = 'PersonalAuto' AND XML_SESSIONS.RATING_STATE = 'NY' AND XML_SESSIONS.ID IN ('72742212', '71289432') ORDER BY XML_SESSIONS.SOURCE_LASTMODIFIED DESC";
return this.sourceJdbcTemplate.query(query, (rs, rowNum) -> {
NYProgramTO to = new NYProgramTO();
to.setRequestXML(rs.getString("REQ_XML"));
to.setSessionId(rs.getString("SESSIONID"));
to.setExpirationDate(rs.getDate("EXPIRATION_DATE"));
to.setQuoteDate(rs.getString("QUOTE_DATE"));
to.setEffectiveDate(rs.getDate("POLICY_EFFECTIVE_DATE"));
to.setCreatedDate(rs.getDate("TARGET_CREATED"));
to.setRatingTransactionID(rs.getString("RATING_TRANSACTION_ID"));
to.setSourceLastModified(rs.getTimestamp("SOURCE_LASTMODIFIED"));
return to;
});
}
Thanks

Correct me if I understood wrong.
If you are looking for something which can give you concatenated value of a column separated with comma, then u should use excel.
There you can paste your data in a column and apply concatenation function available in excel to get you result.
You can refer This link

Sounds like a rather simple java solution. Why don't you write a java method that takes the ids as a string parameter and returns a String formatted the way you need it.
Given you have all ids in one long character sequence/string you can simply do this:
public String toSQLIds(String pRawIds){
String[] ids = pRawIds.split(Pattern.quote("SEPARATOR"));
StringBuilder builder = new StringBuilder();
builder.append("(");
for(int i = 0; i < ids.length; i++){
builder.append("'").append(ids[i]).append("'");
if(i < ids.length-1){
builder.append(", ");
}
}
builder.append(")");
return builder.toString();
}
Something like that. Of course you need the correct separator to successfully split your ids up and format it the way you need it. Run this once with your ids and paste it into your sql.

Related

How to add key and value dynamically and call the procedure in java (Oracle ADF)

ViewObject VO = getViewObjectFromAMImpl("EOView2", "AppModuleDataControl");
Row[] selectedRows = VO.getFilteredRows("tSelect", true);
int counter = 0;
ADFContext adfCtx = ADFContext.getCurrent();
SecurityContext secCntx = adfCtx.getSecurityContext();
String _user = secCntx.getUserName();
//Date vDate = getMinDate();
java.sql.Timestamp startDate = null;
for (Row r : selectedRows) {
startDate = (java.sql.Timestamp) r.getAttribute("StartDate");
if ("E".equals(r.getAttribute("SrcType"))) {
r.setAttribute("Type","S");
r.setAttribute("UpdatedBy", new Date());
r.setAttribute("LastUpdateDate", new Date());
counter++;
}
}
System.out.println("printing count"+counter);
if (counter == 0) {
JSFUtils.addFacesErrorMessage((String) JSFUtils.resolveExpression("No records Approved."));
} else {
Commit();
JSFUtils.addFacesInformationMessage((String) JSFUtils.resolveExpression(" records Approved successfully."));
AdfFacesContext.getCurrentInstance().addPartialTarget(hearderTableBind);
}
approvePopup.cancel();
From the above code i will get the selected rows with key and value pair. I want to add those rows ( Key and Value) to a list and i need to call the procedure. Could you please tell me which is the best possible way to achive this.
I want to call the procedure with key and value pair( Multiple values will come)
You should read the doc at
https://docs.oracle.com/en/middleware/developer-tools/adf/12.2.1.4/develop/extending-business-components-functionality1.html#GUID-B93C7B79-73C9-4434-B12E-A7E23479969A
However, I fail to understand why you need to call a pl/sql procedure at all.
You should be able to do everything in ADF or call a procedure directly without iterating over the data just to set some values.
It's not a good idea to change values in ADF, then call a procedure and assume that the framework somehow knows the changes. The procedure runs in the DB in a different transaction. ADF doesn't know about changes done in the function. The function doesn't know about the changes done in ADF until you post them to the DB.

JHDF5 - How to avoid dataset being overwritten

I am using JHDF5 to log a collection of values to a hdf5 file. I am currently using two ArrayLists to do this, one with the values and one with the names of the values.
ArrayList<String> valueList = new ArrayList<String>();
ArrayList<String> nameList = new ArrayList<String>();
valueList.add("Value1");
valueList.add("Value2");
nameList.add("Name1");
nameList.add("Name2");
IHDF5Writer writer = HDF5Factory.configure("My_Log").keepDataSetsIfTheyExist().writer();
HDF5CompoundType<List<?>> type = writer.compound().getInferredType("", nameList, valueList);
writer.compound().write("log1", type, valueList);
writer.close();
This will log the values in the correct way to the file My_Log and in the dataset "log1". However, this example always overwrites the previous log of the values in the dataset "log1". I want to be able to log to the same dataset everytime, adding the latest log to the next line/index of the dataset. For example, if I were to change the value of "Name2" to "Value3" and log the values, and then change "Name1" to "Value4" and "Name2" to "Value5" and log the values, the dataset should look like this:
I thought the keepDataSetsIfTheyExist() option to would prevent the dataset to be overwritten, but apparently it doesn't work that way.
Something similar to what I want can be achieved in some cases with writer.compound().writeArrayBlock(), and specify by what index the array block shall be written. However, this solution doesn't seem to be compatible with my current code, where I have to use lists for handling my data.
Is there some option to achieve this that I have overlooked, or can't this be done with JHDF5?
I don't think that will work. It is not quite clear to me, but I believe the getInferredType() you are using is creating a data set with 2 name -> value entries. So it is effectively creating an object inside the hdf5. The best solution I could come up with was to read the previous values add them to the valueList before outputting:
ArrayList<String> valueList = new ArrayList<>();
valueList.add("Value1");
valueList.add("Value2");
try (IHDF5Reader reader = HDF5Factory.configure("My_Log.h5").reader()) {
String[] previous = reader.string().readArray("log1");
for (int i = 0; i < previous.length; i++) {
valueList.add(i, previous[i]);
}
} catch (HDF5FileNotFoundException ex) {
// Nothing to do here.
}
MDArray<String> values = new MDArray<>(String.class, new long[]{valueList.size()});
for (int i = 0; i < valueList.size(); i++) {
values.set(valueList.get(i), i);
}
try (IHDF5Writer writer = HDF5Factory.configure("My_Log.h5").writer()) {
writer.string().writeMDArray("log1", values);
}
If you call this code a second time with "Value3" and "Value4" instead, you will get 4 values. This sort of solution might become unpleasant if you start to have hierarchies of datasets however.
To solve your issue, you need to define the dataset log1 as extendible so that it can store an unknown number of log entries (that are generated over time) and write these using a point or hyperslab selection (otherwise, the dataset will be overwritten).
If you are not bound to a specific technology to handle HDF5 files, you may wish to give a look at HDFql which is an high-level language to manage HDF5 files easily. A possible solution for your use-case using HDFql (in Java) is:
public class Example
{
public Class Log
{
String name1;
String name2;
}
public boolean doSomething(Log log)
{
log.name1 = "Value1";
log.name2 = "Value2";
return true;
}
public static void main(String args[])
{
// declare variables
Log log = new Log();
int variableNumber;
// create an HDF5 file named 'My_Log.h5' and use (i.e. open) it
HDFql.execute("CREATE AND USE FILE My_Log.h5");
// create an extendible HDF5 dataset named 'log1' of data type compound
HDFql.execute("CREATE DATASET log1 AS COMPOUND(name1 AS VARCHAR, name2 AS VARCHAR)(0 TO UNLIMITED)");
// register variable 'log' for subsequent usage (by HDFql)
variableNumber = HDFql.variableRegister(log);
// call function 'doSomething' that does something and populates variable 'log' with an entry
while(doSomething(log))
{
// alter (i.e. extend) dataset 'log1' to +1 (i.e. add a new row)
HDFql.execute("ALTER DIMENSION log1 TO +1");
// insert (i.e. write) data stored in variable 'log' into dataset 'log1' using a point selection
HDFql.execute("INSERT INTO log1(-1) VALUES FROM MEMORY " + variableNumber);
}
}
}

Query returning only empty value in java

I am using java to connect with oracle.This is the code which I have used
public List<FavouriteShop> getmyfavouriteshop(String username) {
List<FavouriteShop> res=null;
res = this.getJdbcTemplate().query("select * from(Select tbl_orderdetails.branch_name as myfavourite,tbl_orderdetails.branch_id as branch_id from tbl_orderdetails inner join tbl_ordermaster on tbl_orderdetails.order_master_id=tbl_ordermaster.ordermasterid where tbl_ordermaster.user_id='"+username+"' group by tbl_orderdetails.branch_name,tbl_orderdetails.branch_id order by count(tbl_orderdetails.branch_name) desc) where rownum<=3", new MyFavourite());
return res;
}
private class MyFavourite implements RowMapper<FavouriteShop> {
public FavouriteShop mapRow(ResultSet rs,int i) throws SQLException {
FavouriteShop g=new FavouriteShop();
g.setBranch_id(rs.getString("branch_id"));
g.setMyfavourite(rs.getString("myfavourite"));
return g;
}
}
I tried to execute same query in oracle I am getting output but not here and I am getting only empty result.
First, you have a possible SQL injection. You can avoid this by giving username as an argument to query
this.getJdbcTemplate().query("select * from (... where tbl_ordermaster.user_id=? ...) where rownum<=3",
new Object[]{ username }, new MyFavourite());
A possible reason for the empty result might be
... where tbl_ordermaster.user_id='"+username+"' ...
Usually, user_id is an integer value, but you compare it to a String and enclose it in quotes. Passing username as an argument to query as shown above, should already take care of this.
Usually it is not the same query or not the same database :)
Extract your query text to separate variable, print it to logs. Then copy-paste from logs to sql developer.
And check database and user name.
Also, it is possible that you inserted that entries but forgot to add COMMIT.

How do I call this object to return all strings it finds?

I have the following code that defines a getParts method to find a given Part Name and Part Number in the system. Note that this code comes from our system's API, so if no one can help I'll just delete this question. I figured someone could potentially see a solution or help me along the way.
<%! private QueryResult getParts( String name, String number )
throws WTException, WTPropertyVetoException {
Class cname = wt.part.WTPart.class;
QuerySpec qs = new QuerySpec(cname);
QueryResult qr = null;
qs.appendWhere
(new SearchCondition(cname,
"master>name",
SearchCondition.EQUAL,
name,
false));
qs.appendAnd();
qs.appendWhere
(new SearchCondition(cname,
"master>number",
SearchCondition.EQUAL,
number,
false));
qr = PersistenceHelper.manager.find(qs);
System.out.println("...found: " + qr.size());
return qr;
}
%>
But I would like to allow the user more flexibility in finding these parts. So I set up conditional statements to check for a radio button. This allows them to search by part name and part number, find all, or search using a wildcard. However, I'm having trouble implementing the two latter options.
To attempt to accomplish the above, I have written the below code:
<%
String partName = request.getParameter("nameInput");
String partNumber = request.getParameter("numberInput");
String searchMethod = request.getParameter("selection");
//out.print(searchMethod);
QueryResult myResult = new QueryResult();
if(searchMethod.equals("search"))
myResult = getParts(partName, partNumber);
else if(searchMethod.equals("all"))
{
//Should I write a new function and do this?
//myResult = getAllParts();
//or is there a way I could use a for each loop to accomplish this?
}
//else if(searchMethod.equals("wildcard"))
//get parts matching %wildcard%
while(myResult.hasMoreElements())
{
out.print(myResult.nextElement().toString());
}
%>
Basically, it accepts user input and checks what type of search they would like to perform. Is there an easy way to pass all the values into the myResult object? And likewise for the wildcard search? Like I said before, it may be futile trying to help without access to the API, but hopefully it isn't.
Thanks!
You can (and should) reuse the function, but in order to do so, you will need a part name and number (as those are its input parameters). So for the multi-result options you will need to get a list/collection of part names+numbers and feed them individually to the function, then collect the result in the format that is most appropriate for your needs

Is there a way to get the count size for a JPA Named Query with a result set?

I like the idea of Named Queries in JPA for static queries I'm going to do, but I often want to get the count result for the query as well as a result list from some subset of the query. I'd rather not write two nearly identical NamedQueries. Ideally, what I'd like to have is something like:
#NamedQuery(name = "getAccounts", query = "SELECT a FROM Account")
.
.
Query q = em.createNamedQuery("getAccounts");
List r = q.setFirstResult(s).setMaxResults(m).getResultList();
int count = q.getCount();
So let's say m is 10, s is 0 and there are 400 rows in Account. I would expect r to have a list of 10 items in it, but I'd want to know there are 400 rows total. I could write a second #NamedQuery:
#NamedQuery(name = "getAccountCount", query = "SELECT COUNT(a) FROM Account")
but it seems a DRY violation to do that if I'm always just going to want the count. In this simple case it is easy to keep the two in sync, but if the query changes, it seems less than ideal that I have to update both #NamedQueries to keep the values in line.
A common use case here would be fetching some subset of the items, but needing some way of indicating total count ("Displaying 1-10 of 400").
So the solution I ended up using was to create two #NamedQuerys, one for the result set and one for the count, but capturing the base query in a static string to maintain DRY and ensure that both queries remain consistent. So for the above, I'd have something like:
#NamedQuery(name = "getAccounts", query = "SELECT a" + accountQuery)
#NamedQuery(name = "getAccounts.count", query = "SELECT COUNT(a)" + accountQuery)
.
static final String accountQuery = " FROM Account";
.
Query q = em.createNamedQuery("getAccounts");
List r = q.setFirstResult(s).setMaxResults(m).getResultList();
int count = ((Long)em.createNamedQuery("getAccounts.count").getSingleResult()).intValue();
Obviously, with this example, the query body is trivial and this is overkill. But with much more complex queries, you end up with a single definition of the query body and can ensure you have the two queries in sync. You also get the advantage that the queries are precompiled and at least with Eclipselink, you get validation at startup time instead of when you call the query.
By doing consistent naming between the two queries, it is possible to wrap the body of the code to run both sets just by basing the base name of the query.
Using setFirstResult/setMaxResults do not return a subset of a result set, the query hasn't even been run when you call these methods, they affect the generated SELECT query that will be executed when calling getResultList. If you want to get the total records count, you'll have to SELECT COUNT your entities in a separate query (typically before to paginate).
For a complete example, check out Pagination of Data Sets in a Sample Application using JSF, Catalog Facade Stateless Session, and Java Persistence APIs.
oh well you can use introspection to get named queries annotations like:
String getNamedQueryCode(Class<? extends Object> clazz, String namedQueryKey) {
NamedQueries namedQueriesAnnotation = clazz.getAnnotation(NamedQueries.class);
NamedQuery[] namedQueryAnnotations = namedQueriesAnnotation.value();
String code = null;
for (NamedQuery namedQuery : namedQueryAnnotations) {
if (namedQuery.name().equals(namedQueryKey)) {
code = namedQuery.query();
break;
}
}
if (code == null) {
if (clazz.getSuperclass().getAnnotation(MappedSuperclass.class) != null) {
code = getNamedQueryCode(clazz.getSuperclass(), namedQueryKey);
}
}
//if not found
return code;
}

Categories

Resources