I have an existing SQL Server 2008 database which has a number of views, stored procedures and functions.
I want to be able to SELECT data from one of these SQL functions and limit the number of rows that it returns in a paging scenario.
I have tried using .Select with .Skip and .Take as follows:
public IEnumerable<Product> CallSqlFunction_dbo_Search_Products_View(int clientId,
string environmentCode,
int sessionId)
{
IEnumerable<Product> results;
using (var db = _dbConnectionFactory.Open())
{
results = db.Select<Product>(#"
SELECT
*
FROM
[dbo].[Search_Products_View]
(
#pClientID,
#pEnvironmentCode,
#pSessionId
)", new
{
pClientID = clientId,
pEnvironmentCode = environmentCode,
pSessionId = sessionId
})
.Skip(0)
.Take(1000);
db.Close();
}
return results;
}
This produces the following SQL which is executed on the SQL Server.
exec sp_executesql N'
SELECT
*
FROM
[dbo].[Search_Products_View]
(
#pClientID,
#pEnvironmentCode,
#pSessionId
)',N'#pClientID int,#pEnvironmentCode varchar(8000),#pSessionId int',#pClientID=0,#pEnvironmentCode='LIVE',#pSessionId=12345
It means that this query returns 134,000 products, not the first page of 1000 I was expecting. The paging happens on the API server once the SQL Server has returned 134,000 rows.
Is it possible to use ORMLite so that I can get it to generate the paging in the query similar to this:
exec sp_executesql N'
SELECT
[t1].*
FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY [t0].[ProductId], [t0].[ProductName])
FROM
[dbo].[Search_Products_View](#pClientId, #pEnvironmentCode, #pSessionId) AS [t0]
WHERE
(LOWER([t0].[ProductStatus]) = #pProductStatus1) OR (LOWER([t0].[ProductStatus]) = #pProductStatus2) OR (LOWER([t0].[ProductStatus]) = #pProductStatus3)
) AS [t1]
WHERE
[t1].[ROW_NUMBER] BETWEEN #pPageNumber + 1 AND #pPageNumber + #pNumberOfRowsPerPage
ORDER BY [t1].[ROW_NUMBER]',
N'#pClientId decimal(9,0),#pEnvironmentCode char(3),#pSessionId decimal(9,0),#pProductStatus1 varchar(8000),#pProductStatus2 varchar(8000),#pProductStatus3 varchar(8000),#pPageNumber int,#pNumberOfRowsPerPage int',
#pClientId=0,#pEnvironmentCode='LIVE',#pSessionId=12345,#pProductStatus1='1',#pProductStatus2='2',#pProductStatus3='3',#pPageNumber=0,#pNumberOfRowsPerPage=1000
OrmLite will use the windowing function hack in <= SQL Server 2008 for its typed queries but not for Custom SQL. You'll need to include the entire SQL (inc. Windowing function) into your Custom SQL.
If you do this a lot I'd suggest wrapping the Windowing Function SQL Template in an extension method so you can easily make use of it in your custom queries, e.g:
results = db.Select<Product>(#"
SELECT
*
FROM
[dbo].[Search_Products_View]
(
#pClientID,
#pEnvironmentCode,
#pSessionId
)"
.InWindowingPage(0,1000), new
{
pClientID = clientId,
pEnvironmentCode = environmentCode,
pSessionId = sessionId
})
If you want to use DB Params for the offsets you'll need some coupling to use conventional param names:
results = db.Select<Product>(#"
SELECT
*
FROM
[dbo].[Search_Products_View]
(
#pClientID,
#pEnvironmentCode,
#pSessionId
)"
.InWindowingPage(), new
{
pClientID = clientId,
pEnvironmentCode = environmentCode,
pSessionId = sessionId,
pPageNumber = 0,
pNumberOfRowsPerPage = 100
})
There is a condition if not satisfied then I just want to return no rows as my application will pick no row and will show no record msg on front end. Is there any other professional way?
For now I am using following query to return no row.
select 0
where 1 = 0
Even when you return no rows, you are still returning a schema. And most applications expect the same schema to be returned regardless of the number of rows. Even when 0 rows are returned.
If you can change the SQL in #SqlStr that you are executing with sp_executesql, I would insert into a temporary table in that query and then return the results of selecting from that temporary table:
Select * from #myTempTable where <conditionRequiredForResults>
You said you want to return no rows on your frontend and return nothing. Neither message nor row.
You just need to use if statement to avoid returning anything to your frontend
require_once 'db_connection.php';
$sql = "SELECT * FROM table_name WHERE <your filtering Condition>";
$result = mysqli_query($db_connection, $sql);
if (mysqli_num_rows($result) > 0) {
// If row to be fetched is more than 0
// Return something Example:
echo "Rows detected";
} else {
// If there is no row to be fetched
// Return nothing
}
And this should return nothing if no row fetched from database
this gives accurate result in mssql server
execute proc_Attn_Mon_General 801, '2018-04-14', '2018-05-14', 0
but this gives incomplete result
$query = $this->db->query("execute proc_Attn_Mon_General #emp_id='$emp_id', #date_from='$start_date', #date_to='$end_date', #Aflag=0");
return $query->result_array();
or this
$query = $this->db->query("execute proc_Attn_Mon_General ".$emp_id.",'".$start_date."','".$end_date."', ".$Aflag." ");
return $query->result_array();
am i doing something wrong?
the query works fine but this could be issue of your slow network connection
I have a situation where I need to fetch details of an employee from the database using his ID and display them in the browser.
$sql = "SELECT * FROM employeesalarypayment WHERE empid = ".$val['empid'].";";
$query = $this->db->query($sql);
These are the statements that I have written to get the result array. My problem is how do I take a single field/column from this array? Also have I done it correctly?
Thanks in advance.
If your query return single data from database then you need to use
$row = $query->row_array()
Try this
$sql = "SELECT * FROM employeesalarypayment WHERE empid = ".$val['empid'].";";
$result = $this->db->query($sql)->result_array();
echo $result[0]['field_name'];
I'm trying to convert this SQL query into a linq query but not having much luck.
SELECT DISTINCT gen.ID
, gen.Name
, Ssec.System
FROM dbo.Generic Gen
JOIN dbo.SystemsSelected SSel
ON Gen.RecordID = SSel.RecordID
JOIN dbo.Security SSec
ON (
SSel.SystemA = CASE WHEN Ssec.System = '1stSystem' THEN 1 ELSE NULL END
OR SSel.SystemB = CASE WHEN Ssec.System = '2ndSystem' THEN 1 ELSE NULL END
)
and SSec.Username = 'myUserName'
I've had a look at the following posts but cannot apply the examples to my code:
Link join with case condition
Linq query with table joins
Any help would be appreciated!
Thanks
I cannot answer my own question directly but I found a workaround.
I used linq to instead call a Stored Procedure and that worked fine.
To do this:
1) Save code as a Stored Procedure that accepts a parameter named UserName
2) add the SP into Entity Framework Model
3) call the SP using:
public JsonResult GetNewTeams(string userUserName)
{
using (YourDBNameEntities db = new YourDBNameEntities ())
{
var ret = db.SP_YourStoredProcedureName(userUserName).ToList();
return Json(ret, JsonRequestBehavior.AllowGet);
}
}
Thats it, done, no more scary linq!! :)
sauce: Using stored procedures in LINQ