Is there such a thing as a wildcard for boolean value? - jpa

I have a JPA Repository with a few custom queries. I've been tasked with implementing a functionality which requires numerous new queries. One thing that would drastically cut down on the number of them is if I could use a wildcard for a boolean value.
I have tried modifying the query to use 'LIKE %' but Spring Data doesn't like it, throwing a numberFormatException (Infinite of NaN).
The original query:
#Query("SELECT SUM(paymentSummary.paidAmount) FROM InvoiceLineItem invoice INNER JOIN PaymentSummary paymentSummary"
+ " ON invoice.invoiceKey=paymentSummary.invoiceKey"
+ " WHERE invoice.balanced=:balanced")
BigDecimal getInvoicePaidTotalByBalanced(#Param("balanced") boolean balanced);
Ideally, I'd like to use the same query, but instead of passing it true or false, I'd pass it a wildcard so that it acted on all records regardless of the true/false status.
As of now, the only way I know how to do this is to create a second query, same as the first, minus the where clause.

How about using the IN operator instead? (TRUE, FALSE) will then be your wildcard.
Alternatively, you should be able to use WHERE :balanced IS NULL OR invoice.balanced=:balanced. In that case, change boolean to Boolean and null becomes the wildcard.

Related

SSRS multi value parameter - can't get it to work

First off this is my first attempt at a multi select. I've done a lot of searching but I can't find the answer that works for me.
I have a postgresql query which has bg.revision_key in (_revision_key) which holds the parameter. A side note, we've named all our parameters in the queries with the underscore and they all work, they are single select in SSRS.
In my SSRS report I have a parameter called Revision Key Segment which is the multi select parameter. I've ticked Allow multi value and in Available Values I have value field pointing to revision_key in the dataset.
In my dataset parameter options I have Parameter Value [#revision_key]
In my shared dataset I also have my parameter set to Allow multi value.
For some reason I can't seem to get the multi select to work so I must be missing something somewhere but I've ran out of ideas.
Unlike with SQL Server, when you connect to a database using an ODBC connection, the parameter support is different. You cannot use named parameters and instead have to use the ? syntax.
In order to accommodate multiple values you can concatenate them into a single string and use a like statement to search them. However, this is inefficient. Another approach is to use a function to split the values into an in-line table.
In PostgreSQL you can use an expression like this:
inner join (select CAST(regexp_split_to_table(?, ',') AS int) as filter) as my on my.filter = key_column
Then in the dataset properties, under the parameters tab, use an expression like this to concatenate the values:
=Join(Parameters!Keys.Value, ",")
In other words, the report is concatenating the values into a comma-separated list. The database is splitting them into a table of integers then inner joining on the values.

How to get all data without any filtering in "in" clause

As a part of reporting I want to get some values from database.
Also I included filtering in report UI, like :
select * from invoice where id in (92)
So I am making the postgres statement dynamically(here 92 is the value getting from UI and assigning dynamically). But I want to return all data without any condition if the user select no option, id in this case (no filtering). So how can I handle the "in" clause to return all data without any filtering in this case.
I am asking for a common term that can be included in 'in' clause, so it retun all rows without filtering.
Thanks!
One method is using logic like:
where (v_id is null) or (id = v_id)
Note: be careful about the use of in. It probably will not do what you intend if you expect multiple values to match.

How do I prevent sql injection if I want to build a query in parts within the fatfree framework?

I am using the fatfree framework, and on the front-end I am using jQuery datatables plugin with server-side processing. And thus, my server-side controller may or may not receive a variable number of information, for example a variable number of columns to sort on, a variable number of filtering options and so forth. So if I don't receive any request for sorting, I don't need to have a ORDER BY portion in my query. So I want to generate the query string in parts as per certain conditions and join it at the end to get the final query for execution. But if I do it this way, I won't have any data sanitization which is really bad.
Is there a way I can use the frameworks internal sanitization methods to build the query string in parts? Also is there a better/safer way to do this than how I am approaching it?
Just use parameterized queries. They are here to prevent SQL injection.
Two possible syntaxes are allowed:
with question mark placeholders:
$db->exec('SELECT * FROM mytable WHERE username=? AND category=?',
array(1=>'John',2=>34));
with named placeholders:
$db->exec('SELECT * FROM mytable WHERE username=:name AND category=:cat',
array(':name'=>'John',':cat'=>34));
EDIT:
The parameters are here to filter the field values, not the column names, so to answer more specifically to your question:
you must pass filtering values through parameters to avoid SQL injection
you can check if column names are valid by testing them against an array
Here's a quick example:
$columns=array('category','age','weight');//columns available for filtering/sorting
$sql='SELECT * FROM mytable';
$params=array();
//filtering
$ctr=0;
if (isset($_GET['filter']) && is_array($_GET['filter'])
foreach($_GET['filter'] as $col=>$val)
if (in_array($col,$columns,TRUE)) {//test for column name validity
$sql.=($ctr?' AND ':' WHERE ')."$col=?";
$params[$ctr+1]=$val;
$ctr++;
}
//sorting
$ctr=0;
if (isset($_GET['sort']) && is_array($_GET['sort'])
foreach($_GET['sort'] as $col=>$asc)
if (in_array($col,$columns,TRUE)) {//test for column name validity
$sql.=($ctr?',':' ORDER BY ')."$col ".($asc?'ASC':'DESC');
$ctr++;
}
//execution
$db->exec($sql,$params);
NB: if column names contain weird characters or spaces, they must be quoted: $db->quote($col)

Is there any logical reason to use CFQUERYPARAM in Query of Queries?

I primarily use CFQUERYPARAM to prevent SQL injection. Since Query-of-Queries (QoQ) does not touch the database, is there any logical reason to use CFQUERYPARAM in them? I know that values that do not match the cfsqltype and maxlength will throw an exception, but, these values should already be validated before that and display friendly messages (from a UX viewpoint).
Since Query-of-Queries (QoQ) does not touch the database, is there any logical reason to use CFQUERYPARAM in them? Actually, it does touch the database, the database that you currently have stored in memory. The data in that database could still theoretically be tampered with via some sort of injection from the user. Does that affect your physical database - no. Does that affect the use of the data within your application - yes.
You did not give any specific details but I would err on the side of caution. If ANY of the data you are using to build your query comes from the client then use cfqueryparam in them. If you can guarantee that none of the elements in your query comes from the client then I think it would be okay to not use the cfqueryparam.
As an aside, using cfqueryparam also helps optimize the query for the database although I'm not sure if that is true for query of queries. It also escapes characters for you like apostrophes.
Here is a situation where it's simpler, in my opinion.
<cfquery name="NoVisit" dbtype="query">
select chart_no, patient_name, treatment_date, pr, BillingCompareField
from BillingData
where BillingCompareField not in
(<cfqueryparam cfsqltype="cf_sql_varchar"
value="#ValueList(FinalData.FinalCompareField)#" list="yes">)
</cfquery>
The alternative would be to use QuotedValueList. However, if anything in that value list contained an apostrophe, cfqueryparam will escape it. Otherwise I would have to.
Edit starts here
Here is another example where not using query parameters causes an error.
QueryAddRow(x,2);
QuerySetCell(x,"dt",CreateDate(2001,1,1),1);
QuerySetCell(x,"dt",CreateDate(2001,1,11),2);
</cfscript>
<cfquery name="y" dbtype="query">
select * from x
<!---
where dt in (<cfqueryparam cfsqltype="cf_sql_date" value="#ValueList(x.dt)#" list="yes">)
--->
where dt in (#ValueList(x.dt)#)
</cfquery>
The code as written throws this error:
Query Of Queries runtime error.
Comparison exception while executing IN.
Unsupported Type Comparison Exception:
The IN operator does not support comparison between the following types:
Left hand side expression type = "DATE".
Right hand side expression type = "LONG".
With the query parameter, commented out above, the code executes successfully.

How to convert Lambda Expression to SQL Server Query syntax?

Here's the lambda expression, I want to convert this to SQL Server query syntax.
{x => ((True AndAlso x.Name.ToLower().Contains("_")) AndAlso Not(x.IsDeleted))}
Note : The lambda expression is equivalent to Where Clause of Sql server.
I want to convert it to sql syntax and then pass it to sql server stored procedure.
Is there any way I can achieve this?
Generally, you can use the ToString method on the IQueryable object returned by the LINQ statement to find the exact query that would be executed on the database. But, in this case, I would guess something like this might be generated for the WHERE:
WHERE CONTAINS(Name, '_') AND NOT IsDeleted
But, you haven't provided any detail that would allow me to verify that.
If you don't have full-text on, then the following might be more applicable:
WHERE Name like '%_%' AND NOT IsDeleted