How to use net.java.ao.Query to query issues? - java

I have this select in PostgreSQL:
SELECT "field_1", "field_2","field_3", MIN(COALESCE(NULLIF("field_4",'') ,'TBD')) MINDP,MIN("field_5") MINBOD FROM "MY_TABLE" GROUP BY "field_1", "field_2","field_3"
And I want to use net.java.ao.Query to query my database. My function:
import net.java.ao.Query;
public List<myClass> find() {
String SQL = "SELECT \"field_1\", \"field_2\",\"field_3\", MIN(COALESCE(NULLIF(\"field_4\",'') ,'TBD')) MINDP,MIN(\"field_5\") MINBOD FROM \"MY_TABLE\" GROUP BY \"field_1\", \"field_2\",\"field_3\""
return newArrayList(ao.find(myClass.class, Query.select(SQL)));
}
The problem is: this code return all issues of my table.
When I run this SQL in postgreSQL console it works fine.
My code has different results than SQL console.
Does anybody know why is this happening?

Old question but if somebody steps over this -
Query.select() is not meant to put plain SQL into. It is more of a builder to create 'database independant' query. See some examples here: Finding entities
public MyEntity[] findMyEntities(String fieldValue) {
final Query query = Query.select()
.where("FIELD_VALUE = ?", fieldValue);
// evaluates to something like this
// SELECT * FROM MY_ENTITY WHERE FIELD_VALUE = x;
return ao.find(MyEntity.class, query);
}
This is why there's another method (which you used in your comment), that can handle plain SQL (findWithSQL).
Attention Query and find() often do not work as expected, so you might not get your original query to work using the query builder.

Related

Commons DBUtils Oracle 11.2.0.4 with Java 1.7 Binding parameters SQLException ORA-00942

I'm working with Oracle Database 11.2.0.4 with ojdbc6.jar, and I'm using apache commons dbutils v1.7, with JDK 7. So I'm using the QueryRunner and its method in this function
private <T> List<T> executeQueryAndReturnBeanList(String query, Class<T> className, Object... param) throws SQLException {
Connection connection = getDBConnectionInstance();
DbUtils.loadDriver("oracle.jdbc.driver.OracleDriver");
ResultSetHandler<List<T>> beanListHandler = new BeanListHandler<>(className,new BasicRowProcessor(new GenerousBeanProcessor()));
QueryRunner runner = new QueryRunner();
List<T> list = runner.query(connection, query, beanListHandler, param);
return list;
}
and everything works fine with select query without binding parameters
SELECT * FROM PEOPLE WHERE GRUPPO = 1 AND LANG = 'en_US'
But when I excute this query
String query = "SELECT * FROM PEOPLE WHERE GRUPPO = ? AND LANG = ?";
It gives me this SQL Exception
java.sql.SQLException: ORA-00942: table or view does not exist
Query: SELECT * FROM PEOPLE WHERE GRUPPO = ? AND LANG = ? Parameters: [1, en_US]
at org.apache.commons.dbutils.AbstractQueryRunner.rethrow(AbstractQueryRunner.java:527)
at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:391)
at org.apache.commons.dbutils.QueryRunner.query(QueryRunner.java:252)
at mypackage.executeQueryAndReturnBeanList(JDBCFunctions.java:199)
I really don't know why. I tried to use :P1, :P2 or :1, :2 instead of ? to bind parameters but nothing it happens. Any ideas?
Group is a reserved word and cannot be used as a column or table name. Most probably you have a quoted column name such as "GROUP" within the table.
So, need to query as
SELECT * FROM PEOPLE WHERE "GROUP" = 1 AND LANG = 'en_US'
Quoted table names should be case sensitive, unlike unquoted ones.
The above one is the basic mistake, while the error(ORA-00942) suggests that your application connects to different schema than the schema in which successfully tested the query.
I finally found the solution. I inserted " on every column and table's name and now it works. For example:
String query = "SELECT * FROM \"PEOPLE\" WHERE \"GRUPPO\" = ? AND \"LANG\" = ?"

Issue converting PostgreSQL query to DSLContext

I am trying to convert a query I wrote and tested from the command line to a DSLContext query using jOOq and am encountering issues. The query below is intended to return a list of tags that match the like parameter with a wildcard from a table "campaign" with a JSONB column "tags". This column has values formatted in the following way:
["dogs","cats","rabbits"]
select distinct A.value
from campaign T, LATERAL jsonb_array_elements_text(T.tags) A
where A.value LIKE 't%'
I am attempting to create this to a DSLContext in the following manner but I get an error "ERROR: argument of AND must not return a set". Can anyone see what I can do to resolve this issue and produce the same results from my PostgreSQL query and my DSL query below?
final Field<String> tagField = field("jsonb_array_elements_text(tags)", String.class);
final Table<Record1<String>> lateral =
lateral(sql.dsl().select(a).from(CAMPAIGN)).asTable();
final Result<Record1<String>> tag = sql.dsl()
.select(tagField)
.from(CAMPAIGN, lateral)
.where(tagField.like("t"))
.fetch();
Your query would translate to jOOQ as such:
Field<String> value = field(name("A", "value"), String.class);
sql.dsl()
.selectDistinct(value)
.from(
CAMPAIGN,
lateral(table("jsonb_array_elements_text({0})", CAMPAIGN.TAGS)).as("A"))
.where(value.like("t%"))
.fetch();

Is it possible to use "WHERE" clause to select all records in SQL Statement?

Good Evening, I am curious if it is possible to make a WHERE-clause in a SQL statement which can show all records?
Below some explanation:
Random SQL Statement (Java)-(JSP example), Normal Situation
String SqlStatement = "SELECT * FROM table_example WHERE First_Col = '<%=passVar%>' ";
db.query(SqlStatement );
//........
//........
What if the passVar is 'ALL', and we need to prompt all the records out when passVar = All? I know I can do it with if-else and check if the passVar is "ALL" then query the without-WHERE statement to make it work..
**without-WHERE statement (Java)-(JSP example)**
if(<%=passVar%> == "ALL") {
SqlStatement = "SELECT * FROM table_example";
} else {
SqlStatement = "SELECT * FROM table_example WHERE First_Col = '<%=passVar%>' ";
}
but can I just code one SQL statement to make all the records prompt? Something like below:
(Java)-(JSP example)
String ShowAll = "";
if(<%=passVar%> == "ALL") {
ShowAll = *;
} else {
ShowAll = <%=passVar%>;
}
SqlStatement = "SELECT * FROM table_example WHERE First_Col = ShowAll ";
Try with WHERE 1=1::
Select * from myTable WHERE 1=1
This also works:
WHERE columnname LIKE '%'
Except for NULL values.
where 1=1 worked for me, Although where clause was being used all records were selected.
You can also try
SELECT * FROM Customers
WHERE CustomerID=CustomerID; /* query */
or
[any_column_name]=[column_name_in_LHL]
(LHL=left hand side.)
copy the query and
click here to try code
It would be better to differ the 2 situations and make 2 queries out of it.
If there is no where condition then the DB does not need to evaluate it (potencially faster)
The source code/debugging output is clearer.
Consider moving the special case inside the query itself, e.g.
SELECT * FROM table_example WHERE '<%=passVar%>' IN ('ALL', First_Col)
Try with wildcard value '%' but I would recommend to use a Factory here to create the SQL statement, what you are trying to do smells a bit.
Something else you could do, is making that combination of code and SQL a single query. Which means the IF..ELSE will be in SQL language.
Check these links for some more info:
MySQL
Using If else in SQL Select statement
On sqlserver you can make proc:
create proc select_all_on_null
#a int
as
begin
select * from Records where (#a is null or Record_id=#a )
end
When you select be your program:
make #a in null will select all
if i is numder there will select row with this id

Ebean query using setDistinct() does not work

I'm using an ebean query in the play! framework to find a list of records based on a distinct column. It seems like a pretty simple query but the problem is the ebean method setDistinct(true) isn't actually setting the query to distinct.
My query is:
List<Song> allSongs = Song.find.select("artistName").setDistinct(true).findList();
In my results I get duplicate artist names.
From what I've seen I believe this is the correct syntax but I could be wrong. I'd appreciate any help. Thank you.
I just faced the same issue out of the blue and can not figure it out. As hfs said its been fixed in a later version but if you are stuck for a while you can use
findSet()
So in your example use
List<Song> allSongs = Song.find.select("artistName").setDistinct(true).findSet();
According to issue #158: Add support for using setDistinct (by excluding id property from generated sql) on the Ebean bug tracker, the problem is that an ID column is added to the beginning of the select query implicitly. That makes the distinct keyword act on the ID column, which will always be distinct.
This is supposed to be fixed in Ebean 4.1.2.
As an alternative you can use a native SQL query (SqlQuery).
The mechanism is described here:
https://ebean-orm.github.io/apidocs/com/avaje/ebean/SqlQuery.html
This is from the documentation:
public interface SqlQuery
extends Serializable
Query object for performing native SQL queries that return SqlRow's.
Firstly note that you can use your own sql queries with entity beans by using the SqlSelect annotation. This should be your first approach when wanting to use your own SQL queries.
If ORM Mapping is too tight and constraining for your problem then SqlQuery could be a good approach.
The returned SqlRow objects are similar to a LinkedHashMap with some type conversion support added.
// its typically a good idea to use a named query
// and put the sql in the orm.xml instead of in your code
String sql = "select id, name from customer where name like :name and status_code = :status";
SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
sqlQuery.setParameter("name", "Acme%");
sqlQuery.setParameter("status", "ACTIVE");
// execute the query returning a List of MapBean objects
List<SqlRow> list = sqlQuery.findList();
i have a solution for it:-
RawSql rawSql = RawSqlBuilder
.parse("SELECT distinct CASE WHEN PARENT_EQUIPMENT_NUMBER IS NULL THEN EQUIPMENT_NUMBER ELSE PARENT_EQUIPMENT_NUMBER END AS PARENT_EQUIPMENT_NUMBER " +
"FROM TOOLS_DETAILS").create();
Query<ToolsDetail> query = Ebean.find(ToolsDetail.class);
ExpressionList<ToolsDetail> expressionList = query.setRawSql(rawSql).where();//ToolsDetail.find.where();
if (StringUtils.isNotBlank(sortBy)) {
if (StringUtils.isNotBlank(sortMode) && sortMode.equals("descending")) {
expressionList.setOrderBy("LPAD("+sortBy+", 20) "+"desc");
//expressionList.orderBy().asc(sortBy);
}else if (StringUtils.isNotBlank(sortMode) && sortMode.equals("ascending")) {
expressionList.setOrderBy("LPAD("+sortBy+", 20) "+"asc");
// expressionList.orderBy().asc(sortBy);
} else {
expressionList.setOrderBy("LPAD("+sortBy+", 20) "+"desc");
}
}
if (StringUtils.isNotBlank(fullTextSearch)) {
fullTextSearch = fullTextSearch.replaceAll("\\*","%");
expressionList.disjunction()
.ilike("customerSerialNumber", fullTextSearch)
.ilike("organizationalReference", fullTextSearch)
.ilike("costCentre", fullTextSearch)
.ilike("inventoryKey", fullTextSearch)
.ilike("toolType", fullTextSearch);
}
//add filters for date range
String fromContractStartdate = Controller.request().getQueryString("fm_contract_start_date_from");
String toContractStartdate = Controller.request().getQueryString("fm_contract_start_date_to");
String fromContractEndtdate = Controller.request().getQueryString("fm_contract_end_date_from");
String toContractEnddate = Controller.request().getQueryString("fm_contract_end_date_to");
if(StringUtils.isNotBlank(fromContractStartdate) && StringUtils.isNotBlank(toContractStartdate))
{
Date fromSqlStartDate=new Date(AppUtils.convertStringToDate(fromContractStartdate).getTime());
Date toSqlStartDate=new Date(AppUtils.convertStringToDate(toContractStartdate).getTime());
expressionList.between("fmContractStartDate",fromSqlStartDate,toSqlStartDate);
}if(StringUtils.isNotBlank(fromContractEndtdate) && StringUtils.isNotBlank(toContractEnddate))
{
Date fromSqlEndDate=new Date(AppUtils.convertStringToDate(fromContractEndtdate).getTime());
Date toSqlEndDate=new Date(AppUtils.convertStringToDate(toContractEnddate).getTime());
expressionList.between("fmContractEndDate",fromSqlEndDate,toSqlEndDate);
}
PagedList pagedList = ToolsQueryFilter.getFilter().applyFilters(expressionList).findPagedList(pageNo-1, pageSize);
ToolsListCount toolsListCount = new ToolsListCount();
toolsListCount.setList(pagedList.getList());
toolsListCount.setCount(pagedList.getTotalRowCount());
return toolsListCount;

ORMLite or Query across multiple tables

I am trying to query a table based on criteria from a join table using ORMLite.
Here is how I would express the query I am trying to write in tsql:
select * from media m inner join file f on m.fileId = f.fileId
where m.isNew = 1 OR f.isNew = 1
The result should be a list of media records where either the media record or the corresponding file record has isNew = 1.
I have read through the documentation on using OR in ORMLite, but all of the examples use a single table, not joining. Likewise I have read the documentation on joins, but none of the examples include a where clause that spans both tables. Is there any way besides a raw query to do this?
I had a look at this question: https://stackoverflow.com/a/12629645/874782 and it seems to ask the same thing, but the accepted answer produces an AND query, not an OR. Here is my code that I used to test that theory:
public List<Media> getNewMedia() {
Session session = getSession();
Account account = session.getSelectedAccount();
ContentGroup contentGroup = account.getSelectedContentGroup();
List<Media> results = null;
try {
QueryBuilder<Category, Integer> categoryQueryBuilder = getHelper().getCategoryDao().queryBuilder();
categoryQueryBuilder.where().eq("group_id", contentGroup.getId());
QueryBuilder<MediaCategory, Integer> mediaCatQb = getHelper().getMediaCategoryDao().queryBuilder();
mediaCatQb = mediaCatQb.join(categoryQueryBuilder);
QueryBuilder<FileRecord, Integer> fileQueryBuilder = getHelper().getFileDao().queryBuilder();
fileQueryBuilder.where().ge("lastUpdated", contentGroup.getLastDownload());
QueryBuilder<Media, Integer> mediaQb = getHelper().getMediaDao().queryBuilder();
mediaQb.where().eq("seen", false);
// join with the media query
results = mediaQb.join(fileQueryBuilder).join(mediaCatQb).query();
} catch (SQLException e) {
Log.e(TAG, "Sql Exception", e);
}
return results;
}
For the sake of completion, this is querying for a slightly more complex example than the one I gave above, this one expressed in tsql would be
select * from Media m join FileRecord f on m.fileRecordId = f.fileRecordId
where m.seen = false OR f.lastUpdated >= lastUpdateDate
When I run it, it is actually doing an AND query, which is what I would expect based on two joins with independent where clauses.
I think the key issue is that a where clause is inherently tied to a table, because it is performed on a QueryBuilder object which comes from a Dao that is specific to that table. How can I get around this?
I think what you are looking for is joinOr search for it in the ORMLite docs.
Like join(QueryBuilder) but this combines the WHERE statements of two
query builders with a SQL "OR".

Categories