Using SqlKata from an existing Query - sql-server

I have existing queries used for jobs that run within services to generate reports. Simple things like
"Select * from Transactions"
The jobs will then append parameters to these queries based on preset rules, like Date>Yesterday etc. SqlKata looks like it can do this but I'm not sure how to instantiate the Query object from an existing query. Is something like this possible?
Dim Qry as new Query("Select * from Transactions").OrderByDesc("Date")
Qry.Where("Date", ">", Date.Now().AddDays(-1))
return Qry.Get()

The closest thing that you can do in this case is to wrap the inner query and add conditions on top of it, you can use the SubQuery or CTE approach here.
Something like this, this in C# but the idea is the same.
var existingSql = "select * from transactions";
var query = new Query().FromRaw($"({existingSql}) as inner")
.Where("date", ">=", DateTime.UtcNow.Date);
checkout this example on playground

Related

Dynamic WHERE clause for BETWEEN with Dapper SQL Builder

I am trying to build dynamic WHERE clause with Dapper SQL builder. This works very well for all cases except BETWEEN. Have tried the below approach with BETWEEN (just like IN clause)
SqlBuilder sqlBuilder = new SqlBuilder();
var sqlTemplate = sqlBuilder.AddTemplate(#"Select * from tbl_example /**Where**/");
sqlBuilder.Where(#"Col BETWEEN #colparam", new { paramValue });
con.Query(sqlTemplate.RawSql, sqlTemplate.Parameters);
When using SQL Profiler, I observed that the query generated from dapper looks like
Select * from tbl_example Where Col BETWEEN (#colparam1,#colparam2)
NOTE:
paramValue is an array of Integer which i receive via API
I do understand that this can be written like Col BETWEEN #colparam1 AND #colparam2 or replacing BETWEEN with < and >
As you know, BETWEEN expects two parameters (#colparam1 AND #colparam2), but you're passing only a single one (#colparam).
Assuming that your array contains exactly the boundaries (min and max), try this:
sqlBuilder.Where(#"Col BETWEEN #val1 AND #val2", new { val1 = paramValue[0], val2 = paramValue[1] });

Dapper, SqlBuilder extension and Order By descending

I am trying to build a simple query that retrieves data in descending order using Dapper. The database is MySql if that's important.
This is the code I used:
var builder = new SqlBuilder();
var sql = #$"SELECT * FROM table t /**orderby**/ LIMIT #paramSkip, #paramTake";
var template = builder.AddTemplate(sql);
builder.OrderBy("#paramOrderBy DESC", parameters: new
{
paramOrderBy = orderBy,
});
// Limit
builder.AddParameters(parameters: new
{
paramSkip = skip,
paramTake = take
});
return Connection.QueryAsync<TableModel>(
template.RawSql, template.Parameters,
transaction: Transaction
);
This always returns data in ascending order. DESC is just ignored. I tried using the DESC keyword in the query or as parameter but the result was the same.
Only thing that worked was putting order parameters and DESC keyword in query itself (by string interpolation)
(Edit: Typos and text simplification)
You need your query to look something like this:
... ORDER BY <Column name> DESC ...
A column name cannot be parameterized, so you need to insert it into the query something like this:
builder.OrderBy($"{orderBy} DESC");
If your orderBy originates from the user in any way, be sure to sanitize it first to prevent SQL injection. You could - for instance - keep a list of valid column names and validate against it.

Access SQL Like * alternative in MS SQL server

I'm working on a project that has a search engine. AS we know in MS ACCESS we could use "*" in Queries under Criteria field to retrieve all records.
In SQL Server I need the same technique. I have tried different LIKE with WHERE Clauses. But I still didn't get the exact result I want.
In this project I have 3 textboxes (Category, Item, Location). If the user leaves any of them empty. I want to retrieve all the records.
I need something like this:
string t1,t2,t3;
if(!String.IsNullOrEmpty(txtCategory.Text))
t1=txtCategory.Text;
else
t1="*";
if(!String.IsNullOrEmpty(txtItem.Text))
t2=txtItem.Text;
else
t2="*"
if(!String.IsNullOrEmpty(txtLoc.Text))
t2=txtLoc.Text;
else
t3="*";
-
-
-
// in a function i have this :
SELECT * FROM Table_Items WHERE Category='"+t1+"' AND Item='"+t2+"' AND Location='"+t3+"'"
in ms sql server you can use the same technique but instead of * you should use %.
for examples:
%: means any
a%: all strings that start with a
%z: all strings that end with z
SO, your code should look like something as below:
// codes here
t3="%";
WHERE ColumnName LIKE t3
or
Where ColumnName LIKE '%'
I hope that will help you.
Change your * to the %
... Where Category Like "'+t1+"' and Item Like '"+t2+"' ...

PostgreSQL query not working in Yii2

I want to execute query in my yii2 application. I'm using PostgreSQl. There is a table called list inside the user schema. If I try to build any query it returns 1. My code is here:
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list"
')->execute();
Please show me my mistake in the query above.
This is not related to the DB type in Yii2 if you want the result of a single value you should use queryScalar() instead of execute()
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list" ')->queryScalar();

Sort a LINQ with another LINQ in MVC

Using SQL Server Management
Using MVC VS 2013 for Web
Being in a Controller
Here materialnumb it's a LINQ query that always return only one value.
Being the following...
var materialnumb = (from r in db.MaterialNumber
where r.MaterialNumber == 80254842
select r.MaterialNumber);
I have another LINQ query from a SQL view that involves several other tables with inner join statements and so on (which includes the previous table db.MaterialNumber) that goes like this:
var query = (from r in db.SQLViewFinalTable
where r.MaterialNumber == Convert.ToInt32(materialnumb.MaterialNumber)
select r
I want to sort all the materials by the retrieved material number from the first query but it drops the following error when I try to pass the query as a model for my View:
LINQ to Entities does not recognize the method 'Int32
ToInt32(System.String)' method, and this method cannot be translated
into a store expression.
I assume this is because the query is an object even if its has just one value so it can't be converted into a single Int32.
Even more, the query it's not being executed, it's just a query...
So, how can achieve my goal?
Additional information: I tried to convert the query outside the "final" query. It still doesn't work.
Additional information: This is just an example, the true query actually has several more other querys embedded and this other querys have also other querys in them, so I need a practical way.
Additional information: I have also tried to convert the query into a string and then again into an int.
Try this:
var materialnumb = (from r in db.MaterialNumber
where r.MaterialNumber == 80254842
select r.MaterialNumber).FirstOrDefault();
var query = from r in db.SQLViewFinalTable
where r.MaterialNumber == materialnumb
select r
But I can not get whay are you filtering by 80254842 and selecting the same value? You can do directly:
var query = from r in db.SQLViewFinalTable
where r.MaterialNumber == 80254842
select r

Resources