jdbi #sqlquery: could not determine data type of parameter $1 - sql

I am trying to add optional/nullable parameters to my sql query.
#SqlQuery("select * from temp where param1 = :param1")
List<Temp> findValues(#Bind("param1") String param1)
Problem: param can be null. So I tried to add null check in the sql query.
SqlQuery("select * from temp where ( (:param1 is not null) and (param1 = :param1"))
This throws the following error:
org.skife.jdbi.v2.exceptions.UnableToExecuteStatementException: org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $1
In my problem I have to add multiple params all of which are nullable. (optional filters)
NOTE coalesce(:param1, param1) = param1 : doesn't work quite right. If param1 is sent, it gives back results where value is either param1 value, or null.
How can I make this null check work? Or is there a way that I can generate the sql query and pass it as a string to #SqlQuery?
I have looked everywhere but can't seem to find a solution. Any help would be appreciated.

If you want to use it as optional filters, you could use #Define. Using #Define, you define attributes for the template engine to use(jdbi v2 uses ST v3). Then, your example would look like something like this:
#SqlQuery("SELECT * FROM temp WHERE 1 = 1 <if(PARAM1)> AND param1 = :param1 <endif>)
List<Temp> findValues(#Define("PARAM1") #Bind("param1") String param1)
So, in this way, if value for param1 is null, query will look like:
SELECT * FROM temp WHERE 1 = 1
otherwise:
SELECT * FROM temp WHERE 1 = 1 AND param1 = :param1

Related

LIKE with integers in PostgreeSQL using R

I need to download a table from postgree to R, but filtered by part of an INT.
I have been trying:
library(RPostgreSQL)
con <- dbConnect(PostgreSQL(), user= "#####", dbname="######",password="#####"
,host="#####", port='######')
vetor_id <- c("83052407","10406587","12272377")
match_id <- dbGetQuery(con,paste("
SELECT *
FROM public.data2015
WHERE id IN ('", paste(vetor_id,collapse = "','"),"')
",sep = ""))
dbDisconnect(con)
I also tried CONTAINS but didn't work.WHERE Contains(id,", paste(vetor_id,collapse = " OR "),"')
id is INT and vetor_id is just part of the values. I mean,vector_id = 83052407 must find id = 83052407000132.
How can I use something like LIKE and put vetor_id% ?
Is this what you want?
WHERE id::text like ? || '%'
This converts the integer id to a string, and attempts to match it against the parameter. If id starts with the parameter, the condition is satisfied.
Note that this uses a legitimate query parameter (represented by the question mark): you should get used to parameterize your queries rather than concatenating variables in the query string: this is cleaner, more efficient and safer.

Select Specific Column from a Linked Server Table

I have the following C# code to select a column from a table that is on a linked server:
var query2 = $#"select [FileName] from [AMS_H2H].[H2H].[dbo].[FileReconciliation] where ProductCode = #productCode";
LayZConnection(); //make the db connection
var candidates = _dbConnection.Query<int>(query2, new { productCode = "ACHDH" });
When running it, I get the following error:
"Input string was not in a correct format."
If my query is instead the following, where I select all columns, it works:
var query2 = $#"select * from [AMS_H2H].[H2H].[dbo].[FileReconciliation]
What is the correct format to select just the FileName. Btw, the first query works fine from MSSMS.
You're specifying a type of int in Query<int>, which will cause Dapper to try and map the result of the query to an integer, however your query is returning a filename in select [FileName], which would suggest that it is a string.
Changing the type Query<string> should solve the issue.
More information on Dapper's Query method is available in Dapper's documentation

multiple where statements in big select

I have 2 search params.
I can pass nothing and then I must get all rows from DB.
OR I can pass Param1 and get row where ADB.param1=param1
OR I can pass Param2 and get row where ADB.param2=param2
OR I can pass Param1 and Param2 and get row where ADB.param1=param1
and ADB.param2=param2
Let's imagine that I have DB like
CarColor,CarType,CarEngineVolume,CarMakeName
param1 is CarColor
param2 is CarType
if I Select DB without sending params I must get the whole list of rows
red,sedan,2.0,Honda
blue,sedan,3.0,Bmw
green,pickup,4.0,Ford
If I send only param2 for example "sedan"
I must get the following list
red,sedan,2.0,Honda
blue,sedan,3.0,Bmw
but if I send both params for example param1 "red" and param2 "sedan"
then I must get only 1 row
red,sedan,2.0,Honda
If I deal only with one parameter in my where
WHERE ( (ADB.param1 = COALESCE(#param1, ADB.param1))
then when I send param1 I get only one row and all rows if param1 is null and its OK
but when I add second parameter check
WHERE ( (ADB.param1 = COALESCE(#param1, ADB.param1))
AND (BDB.param2 = COALESCE(#param2 , BDB.param2)) )
I get nothing when sending only param1.
But I still must get 1 row. But get nothing :(
use OR instead AND
WHERE ( (ADB.param1 = COALESCE(#param1, ADB.param1))
OR (BDB.param2 = COALESCE(#param2 , BDB.param2)) )
You can use this.
WHERE ( ( #param1 IS NULL OR ( ADB.param1 = #param1 ))
AND ( #param2 IS NULL OR ( BDB.param2 = #param2 ))
AND ( ADB.param1 IS NOT NULL OR ADB.param2 IS NOT NULL ) )

QueryDSL like operation SimplePath

Similarly to this question I would like to perform an SQL "like" operation using my own user defined type called "AccountNumber".
The QueryDSL Entity class the field which defines the column looks like this:
public final SimplePath<com.myorg.types.AccountNumber> accountNumber;
I have tried the following code to achieve a "like" operation in SQL but get an error when the types are compared before the query is run:
final Path path=QBusinessEvent.businessEvent.accountNumber;
final Expression<AccountNumber> constant = Expressions.constant(AccountNumber.valueOfWithWildcard(pRegion.toString()));
final BooleanExpression booleanOperation = Expressions.booleanOperation(Ops.STARTS_WITH, path, constant);
expressionBuilder.and(booleanOperation);
The error is:
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [7!%%] did not match expected type [com.myorg.types.AccountNumber (n/a)]
Has anyone ever been able to achieve this using QueryDSL/JPA combination?
Did you try using a String constant instead?
Path<?> path = QBusinessEvent.businessEvent.accountNumber;
Expression<String> constant = Expressions.constant(pRegion.toString());
Predicate predicate = Expressions.predicate(Ops.STARTS_WITH, path, constant);
In the end, I was given a tip by my colleague to do the following:
if (pRegion != null) {
expressionBuilder.and(Expressions.booleanTemplate("{0} like concat({1}, '%')", qBusinessEvent.accountNumber, pRegion));
}
This seems to do the trick!
It seems like there is bug/ambiguity. In my case, I need to search by couple fields with different types (String, Number), e.g. SQL looks like:
SELECT * FROM table AS t WHERE t.name = "%some%" OR t.id = "%some%";
My code looks like:
BooleanBuilder where = _getDefaultPredicateBuilder();
BooleanBuilder whereLike = new BooleanBuilder();
for(String likeField: _likeFields){
whereLike = whereLike.or(_pathBuilder.getString(likeField).contains(likeValue));
}
where.and(whereLike);
If first _likeFields is type of String - request works fine, otherwise it throws Exception.

nhibernate hql subquery : convert null to zero

I am trying to update sum of particular amount from one table as a value in another table, but getting problem when the particular id does not exist in another table :
the hql i have looks like beow:
var session = SessionManager.GetCurrentSession();
var queryString = string.Empty;
queryString += #"update CLiner cl set cl.UnbilledDue =
(select sum(cu.UnbilledAmount) as UnbilledAmount from CUnbilled cu
where cu.AccountNo = cl.AccountNo and cu.FileDate = :fileDate)
where cl.FileDate = :fileDate ";
var query = session.CreateQuery(queryString);
query.SetDateTime("fileDate", new DateTime(2014, 10, 7));
query.ExecuteUpdate();
but its giving exception when the particular account no does not exist in child table and the sum is returned as zero.
i tried changing the subquery select to
select isnull(sum(cu.UnbilledAmount),0) as UnbilledAmount
which as expected is not supported by nhibernate hql. so there a way i can convert null to zero in hql select statement...
Try this:
coalesce(sum(cu.UnbilledAccount), 0)
Reason:
Normally when you wirte a SQL query to prevent NULL you must apply an ISNULL function over the SELECT, in this way:
ISNULL(SELECT sum(...., 0) or COALESCE(SELECT sum(...., 0) (return the same result but COALESCE can applied with more parameter, ISNULL has only two parameters)
but in HQL isn't possible, so you can use COALESCE function to prevent that behaviour.