I want use where when input variable is not null.
For example, when #custid is not null create this query:
Select *
from customers
where custid = #custid
and when #custid is null, then use this query instead:
Select *
from customers
How can I do this?
I searched on google, but haven't found any similar answer. Thanks
You can use the following query:
Select *
from customers
where #custid IS NULL OR custid=#custid
In this case if your variable is null only the condition #custid IS NULL will be evaluated and you get query identical to Select * from customers
If your variable is not null then condition #custid IS NULL is false and your query is identical to Select * from customers where custid=#custid
I use a SqlBuilder class and provide filters that attach the WHERE clauses programmatically.
So the SqlBuilder class would look like this:
public class Program
{
public static void Main()
{
Console.WriteLine(SqlBuilder.GetSql(null));
Console.WriteLine(SqlBuilder.GetSql("CUSTOMER_ID"));
}
public class SqlBuilder{
private static string _baseSql = "select * from customers";
public static string GetSql(string customerId){
var final = _baseSql;
if(customerId != null)
final += " WHERE custId=#custId";
return final;
}
}
}
This can also be made generic through the use of parameters and enums.
Related
when i query a single table , i do not want all columns , i just want some column that i interest in.
For example, when i use where method to query a table, it will query all columns in a table like
public class SubjectSpecimenType extends Model {
}
SubjectSpecimenType.where("SUBJECT_ID = ? AND SITE_ID = ?", subjectId, siteId);
i don't know if there has a method named select that i can use to query some column like
SubjectSpecimenType.select("SUBJECT_NAME", "SITE_NAME").where("SUBJECT_ID = ? AND SITE_ID = ?", subjectId, siteId);
there are the source code in LazyList.java
/**
* Use to see what SQL will be sent to the database.
*
* #param showParameters true to see parameter values, false not to.
* #return SQL in a dialect for current connection which will be used if you start querying this
* list.
*/
public String toSql(boolean showParameters) {
String sql;
if(forPaginator){
sql = metaModel.getDialect().formSelect(null, null, fullQuery, orderBys, limit, offset);
}else{
sql = fullQuery != null ? fullQuery
: metaModel.getDialect().formSelect(metaModel.getTableName(), null, subQuery, orderBys, limit, offset);
}
if (showParameters) {
StringBuilder sb = new StringBuilder(sql).append(", with parameters: ");
join(sb, params, ", ");
sql = sb.toString();
}
return sql;
}
when call formSelect method, the second param columns always be null
is there a unfinish TODO ?
When operating on Models, ActiveJDBC always selects all columns, because if you load a model and it has partial attributes loaded, then you have a deficient model. The columns are specified in some edge cases, as in the RawPaginator: https://github.com/javalite/javalite/blob/e91ebdd1e4958bc0965d7ee99e6b7debc59a7b85/activejdbc/src/main/java/org/javalite/activejdbc/RawPaginator.java#L141
There is nothing to finish here, the behavior is intentional.
I have a table with several columns and I'm looking to create a function that will return the sum of all the entries in a particular column.
For debug purposes, I've simply set the return string to "1" to confirm the rest of my code works properly, which it does.
Can anyone help me with the necessary code to sum the column and return the value?
public String TotalServings(){
SQLiteDatabase db = getReadableDatabase();
//From the table "TABLE_PRODUCTS" I want to sum all the entries in the column "COLUMN_SERVINGS"
String Servings = "1";
return Servings;
}
Here's what you need:
//This method returns an int, if u need it string parse it
public Int TotalServings(){
int serving =0;
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery(
"SELECT SUM(COLUMN_SERVINGS) FROM TABLE_PRODUCTS", null);
if(cursor.moveToFirst()) {
serving = cursor.getInt(0);
}
return serving;
}
What I'm trying to achieve is to make dynamic a series of replacements that have to be performed on a certain field. (To make things even easier, I want in fact to remove data, so I'll be always comparing with
Say that sometimes I will have to do just one replacement:
... REPLACE(myField, stringToRemove, '')
Sometimes, I will need two replacements:
... REPLACE(REPLACE(myField, stringToRemove, ''), anotherStringToRemove, '')
However, I need to make this dynamic and I do not know in advance how many of those values I'll have, and so, how many replacements (removals) I'll have to do.
I tried searching for aggregate string manipulation functions and, of course, there's none. I also know that this can be achieved through a CLR aggregate function but I don't have the possibility of using it.
Any ideas?
You can setup a table variable with FromValue and ToValue and use a while loop to do the replacements.
-- Table to replace in
declare #T table
(
Value varchar(50)
)
insert into #T values
('first second third'),
('first second third')
-- Table with strings to replace
declare #Rep table
(
ID int identity primary key,
FromValue varchar(50),
ToValue varchar(50)
)
insert into #Rep values
('second', 'fourth'),
('third', 'fifth')
declare #ID int
select #ID = max(ID)
from #Rep
while #ID > 0
begin
update #T
set Value = replace(Value, FromValue, ToValue)
from #Rep
where ID = #ID
set #ID -= 1
end
select *
from #T
Result:
Value
-------------------
first fourth fifth
first fourth fifth
If you only want to query the values you can do something like this.
;with C as
(
select 0 as ID,
Value,
0 as Lvl
from #T
union all
select R.ID,
cast(replace(C.Value, R.FromValue, R.ToValue) as varchar(50)),
Lvl + 1
from #Rep as R
inner join C
on C.ID + 1 = R.ID
)
select top 1 with ties Value
from C
order by Lvl desc
Once you implement the CLR aggregate function below, you can do:
SELECT dbo.ReplaceAgg(t.[text], w.badword, w.goodword) // call CLR aggregate function
FROM [Texts] t CROSS JOIN BadWords w
GROUP BY t.[text]
CLR aggregate function in C#
/// <summary>
/// Allows to apply regex-replace operations to the same string.
/// For example:
/// SELECT dbo.ReplaceAgg(t.[text], w.badpattern, "...")
/// FROM [Texts] t CROSS JOIN BadPatterns w
/// GROUP BY t.[text]
/// </summary>
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate(Format.UserDefined,
IsInvariantToDuplicates = true, IsInvariantToOrder = false,
IsInvariantToNulls = true, MaxByteSize = -1)]
public class RegexReplaceAgg : IBinarySerialize
{
private string str;
private string needle;
private string replacement;
public void Init()
{
str = null;
needle = null;
replacement = null;
}
public void Accumulate(SqlString haystack, SqlString needle, SqlString replacement)
{
// Null values are excluded from aggregate.
if (needle.IsNull) return;
if (replacement.IsNull) return;
if (haystack.IsNull) return;
str = str ?? haystack.Value;
this.needle = needle.Value;
this.replacement = replacement.Value;
str = Regex.Replace(str, this.needle, this.replacement, RegexOptions.Compiled | RegexOptions.CultureInvariant);
}
public void Merge(RegexReplaceAgg group)
{
Accumulate(group.Terminate(), new SqlString(needle), new SqlString(replacement));
}
public SqlString Terminate() => new SqlString(str);
public void Read(BinaryReader r)
{
str = r.ReadString();
needle = r.ReadString();
replacement = r.ReadString();
}
public void Write(BinaryWriter w)
{
w.Write(str);
w.Write(needle);
w.Write(replacement);
}
}
You might have to write a scalar function to which you pass the original string, and enough information for it to know which strings to remove, and have it loop through them and return the result of the set of replacements.
I am new to android programming, I am doing a simple SELECT with a rawquery and it is giving me an error...
Here's my code
public Cursor getSubCategory(int categoryID){
String select = "SELECT subcategory_name FROM subcategory WHERE id_category = " + categoryID;
return mDb.rawQuery(select, null);
}
As you can see the id_category is an Integer
If anyone has ideas it would be great
Your not using the API to its full advantage there you should use
String select = "SELECT subcategory_name FROM subcategory WHERE id_category = ?"
and then pass in the categoryID to the second argument like
...
String[] arguments = { categoryID.toString() }
return mDb.rawQuery(select, arguments);
...
This should remove SQL injection risks as you are using parameters (the "?").
Apart from that we will need more details about the error to help you further
What is the best way to have a select query which has an argument which can be NULL depending on some variable in the program?
I can think of two solutions (pseudocode):
bool valueIsNull;
int value;
query = "SELECT * FROM table WHERE field ";
if (valueIsNull)
{
query += "IS NULL";
}
else
{
query += "= ?";
}
statement st = sql.prepare(query);
if (!valueIsNull)
{
st.bind(0, value);
}
or
bool valueIsNull;
int value;
query = "SELECT * FROM table WHERE field = ? OR (? IS NULL AND field IS NULL)";
statement st = sql.prepare(query);
if (valueIsNull)
{
st.bindNull(0);
st.bindNull(1);
}
else
{
st.bind(0, value);
st.bind(1, value);
}
It is a lot of code for just a simple SELECT statement and I find it just ugly and unclear.
The cleanest way would be something like:
bool valueIsNull;
int value;
query = "SELECT * FROM table WHERE field = ?"; // <-- this does not work
statement st = sql.prepare(query);
st.bind(0, value, valueIsNull); // <-- this works
Obviously this does not work. But is there a clean way to handle this?
I do not think it matter much but I am using C++, cppdb and postgresql.
With Postgresql (but I believe not standard) you can use
SELECT * from some_table where field IS NOT DISTINCT FROM ?;
IS NOT DISTINCT FROM, unlike plain =, is true when both sides are NULL.
As you've noted, the main problem with this:
SELECT * FROM table WHERE field = ? OR (? IS NULL AND field IS NULL)
is that it is actually two parameters which need to be bound.
You can get around that with a (should be fairly portable) construct like:
SELECT *
FROM table
INNER JOIN (SELECT ? AS param1 /* FROM DUAL */) AS params
ON 1 = 1
WHERE field = param1
OR COALESCE(param1, field) IS NULL