Linq-to-SQL date format: query does not work - c#

I have a stored procedure when I am executing this query in SQL Server
exec SelectOfficeNameGroup '2011-10-05', '2011-11-09', ''
it returns 110 rows.
Now I have two datepicker on my c# 3.5 form and one button which executes the query like this:
var result = context.SelectOfficeNameGroup(dateTimePickerFrom.Value, dateTimePickerTo.Value, "");
but its only returns 2 rows.
My date picker's format is MM/DD/YYYY
This is my procedure
ALTER PROC [dbo].[SelectOfficeNameGroup]
#From datetime,
#To datetime,
#OfficeName nvarchar(50)
AS
BEGIN
SELECT
ID AS ProductID, OfficeName,
SUM(Quantity) AS Quantity,
SUM(TotalPrice) AS TotalPrice,
Category
FROM
ProductLogWithCategory
WHERE
DateTime BETWEEN #From AND #To AND OfficeName = #OfficeName
GROUP BY
OfficeName, ID, Category
return
END
Any advice?

Try with
var result = context.SelectOfficeNameGroup(dateTimePickerFrom.Value.ToString("yyyy-MM-dd"), dateTimePickerTo.Value.ToString("yyyy-MM-dd"), "");
Have a look at the DateTime.ToString documentation
Update
Just to be on the safe side try
ALTER PROC [dbo].[SelectOfficeNameGroup]
#From varchar(8),
#To varchar(8),
#OfficeName nvarchar(50)
AS
BEGIN
SELECT
ID AS ProductID, OfficeName,
SUM(Quantity) AS Quantity,
SUM(TotalPrice) AS TotalPrice,
Category
FROM
ProductLogWithCategory
WHERE
DateTime BETWEEN #From AND #To AND OfficeName = #OfficeName
GROUP BY
OfficeName, ID, Category
return
END
and use it like this
from sql
exec SelectOfficeNameGroup '20111005', '20111109', ''
from linq
var result = context.SelectOfficeNameGroup(dateTimePickerFrom.Value.ToString("yyyyMMdd"), dateTimePickerTo.Value.ToString("yyyyMMdd"), "");

DateTime.Parse('your date in MM/DD/YYYY', new CultureInfo("en-US")).ToString("yyyy-MM-dd")

Related

Convert lag, Partition by in SQL to LINQ Lambda

I have an existing table #temp with below format
#temp(id bigint, pid varchar(50), pdt date)
How do i convert the below SQL Query to Linq Lambda
create table #tempResultSet
(
id bigint,
pid varchar(20),
pdt date,
pdt1 date,
daydiff as datediff(day,pdt,pdt1)
)
insert into #tempResultSet
SELECT id, pid, pdt,
isnull(lead(pdt) OVER (PARTITION BY pid ORDER BY pdt),
lag(pdt) OVER (PARTITION BY pid ORDER BY pdt)) pdt1
FROM #temp
Assuming #temp and #tempResultSet are both configured properly, you can use linq2db's support for window functions to get what you want.
Below is a snippet of what I believe would be the correct syntax in this case, though I haven't tested it, and I don't have experience using linq2db. I hope it helps:
var q =
from temp in dbContext.Temp
select new TempResultSet
{
Id = temp.id,
Pid = temp.pid,
Pdt = temp.pdt,
IsNull = Sql.Ext.Lead(temp.pdt)
.Over()
.PartitionBy(temp.pid)
.OrderBy(temp.pdt)
.ToValue() is null,
Pdt1 = Sql.Ext.Lag(temp.pdt)
.Over()
.PartitionBy(temp.pid)
.OrderBy(temp.pdt)
};
dbContext.AddRange(q.ToArray());
dbContext.SaveChanges();

Error converting varchar to datetime when running stored procedure from code

From within my C# app I'm calling a stored procedure using Dapper:
return conn.Query<MyList>("check_data", new { dataToCheck }, commandType: CommandType.StoredProcedure);
dataToCheck is a DataTable because check_data accepts a TVP. This table type has 2 columns (from_date varchar(20), to_date varchar(20)) and is based on the following class.
public class DataToCheckType
{
public DateTime? from_date {get; set;}
public DateTime? to_date {get; set;}
}
Dapper then sends the following to SQL Server:
declare #p1 dbo.CheckDataType
insert into #p1 values('2017-04-19 00:00:00','2017-04-19 00:00:00')
exec check_data #dataToCheck=#p1
The SP itself is simple. It calls a function that builds a SQL statement which is then executed:
DECLARE #sql nvarchar(max) = dbo.GetSql(#dataToCheck);
DECLARE #results TABLE (Id int);
INSERT INTO #results EXECUTE(#sql);
The GetSql function starts like this:
DECLARE #fromDate datetime;
DECLARE #toDate datetime;
SELECT
#fromDate = CONVERT(datetime, from_date, 120),
#toDate = CONVERT(datetime, to_date, 120),
FROM
#dataToCheck;
And it continues building the SQL statement as expected. When running the SP from T-SQL everything works fine.
However, when running the same from code I get the following error:
check_data : 241 Conversion failed when converting date and/or time from character string
Why does the SP work in T-SQL but not when calling it from code? What is wrong with the dates?
The problem was solved by changing the columns in the table type from varchar(20) to date.

Sql server get result of one month before

I have the following query
DECLARE #StartDate DATETIME, #EndDate DATETIME
SET #StartDate = DATEADD(mm,-1, getdate())
select count(status) from [full]
where (date_reception> #StartDate and status = 'OPEN')
I need to get result of one month before now , for example we are in 2015-03-19 i need to get result from 2015-02-19 till now.
When i try query above i get as result (4412) and when i try (where date_reception >'2015-02-19') i get (5638)
If the time component of the date is not to be considered, try the following code. If it is, your current code seems accurate.
DECLARE #StartDate DATETIME, #EndDate DATETIME, #currentDate date
set #currentDate = GETDATE()
SET #StartDate = DATEADD(mm,-1, #currentDate))
select count(status) from [full]
where (date_reception> #StartDate and status = 'OPEN')
try
WHERE date_reception BETWEEN DATEADD(month, -1, GETDATE()) AND DATEADD(GETDATE())

IN Clause with WHERE clause not getting proper results in SQL Server

SELECT Col1, Col2, Col3, Col4
FROM Table1
WHERE User1 = #Owner
AND group1 = #Group
AND date1 BETWEEN #startDate AND #endDate
AND Mail LIKE #email
AND def IN (CASE #InvoiceMethod //Problem is Here
WHEN ''
THEN def
ELSE (#InvoiceMethod)
END)
A piece of code from the stored procedure. If am executing this, it's not returning any rows, even though it has some to return. Problem is with the IN clause, if I didn't pass anything to IN clause i.e #InvoiceMethod is null, then I'm getting rows.
If I pass anything to #InvoiceMethod, I'm not getting any rows.
The value in #InvoiceMethod is = 'A','B'
I tried many combinations like 'A','B' or "A","B" without any results.
How to pass values to IN clause please? In which format?
Please help me out of this.
Modified the stored procedure to the following,
Declare #tmpt table (value nvarchar(5) not null)
SET #InvoiceCount=(select COUNT(*) from dbo.fnSplit(#InvoiceMethod, ','))
SET #tempVar=1;
WHILE #tempVar<=(#InvoiceCount)
BEGIN
INSERT INTO #tmpt (value)
VALUES (#InvoiceMethod);//Here i need to insert array of values to temp table.like invoicemethod[0],invoicemethod[1]&invoicemethod[2] depends on #InvoiceCount
SET #tempVar=#tempVar+1;
END
--DECLARE #tmpt TABLE (value NVARCHAR(5) NOT NULL)
--INSERT INTO #tmpt (value) VALUES (#InvoiceMethod);
SELECT Col1,Col2,Col3,Col4
FROM Table1
WHERE User1 = #Owner
AND group1 = #Group
AND date1 between #startDate AND #endDate
AND Mail LIKE #email
AND def IN (SELECT value FROM #tmpt)
But not getting the results as expected :(
IMO this isn't a good way to approach this problem, by passing a list of filter values for a column in a comma separated string, as this is almost encouraging a Dynamic Sql approach to the problem (i.e. where you EXEC a built Sql string which pastes in the #InvoiceMethod as a string).
Instead, Sql 2008 has Table Valued Parameters, (and prior to this, you could use Xml), which allows you to pass structured data into a procedure in a table format.
You then just need to join to this table parameter to effect the 1..N valued IN () filtering.
CREATE TYPE ttInvoiceMethods AS TABLE
(
Method VARCHAR(20)
);
GO
CREATE PROCEDURE dbo.SomeProc
(
#InvoiceMethod ttInvoiceMethods READONLY, -- ... Other Params here
)
AS
begin
SELECT Col1, Col2, ...
FROM Table1
INNER JOIN #InvoiceMethod
ON Table1.def = #InvoiceMethod.Method -- Join here
WHERE User1 = #Owner
... Other Filters here
END
Have a look here for a similar solution with a fiddle.
Edit
The optional parameter (#InvoiceMethod = '') can be handled by changing the JOIN to the TVP with a subquery:
WHERE
-- ... Other filters
AND (Table1.def IN (SELECT Method FROM #InvoiceMethod))
OR #InvoiceMethod IS NULL)
To Initialize a TVP to NULL, just don't bind to it in C# at all.
I think a variable represetning multiple values with comma is not allowed in the in clause. You should either use string fiunctions (split and join) or go with the temp table solution. I prefer the second.
Use a temporary table to store your values and then pass it to your in statement
DECLARE #tmpt TABLE (value NVARCHAR(5) NOT NULL)
INSERT INTO #tmpt .........
...
...
SELECT Col1,Col2,Col3,Col4
FROM Table1
WHERE User1 = #Owner
AND group1 = #Group
AND date1 BETWEEN #startDate AND #endDate
AND Mail LIKE #email
AND def IN (SELECT value FROM #tmpt)
Used Splitfunctions to resolve the issue,Modified SQL Query
SELECT Col1, Col2, Col3, Col4
FROM Table1
WHERE User1 = #Owner
AND group1 = #Group
AND date1 BETWEEN #startDate AND #endDate
AND Mail LIKE #email
AND def IN (SELECT * FROM sptFunction(#InvoiceMethod,',')) //Problem is Here (Solved by using split functions)

Using the Inserted Value To Return A String From Lookup Sql

I have a stored procedure which inserts a customer into a SQL Server Database:
#Name varchar(50),
#Country int,
#DateRegistered datetime,
#NumberOfEmployees int,
#ID int output,
AS
INSERT INTO AccountManagementChristian.dbo.Customer(Name, CountryID, DateRegistered, EmployeeRangeID)
VALUES(#Name, #Country, #DateRegistered, #NumberOfEmployees)
SET #ID = ##IDENTITY
I also have a look up table with the Country ID and Country Name and another lookup table with the EmployeeRange ID and the Number of Employees. Both Country Name and Number of Employees are strings.
When inserting I need to be able to return the country name string that corresponds to the country ID that is inserted and the same for the Country Name and Country ID?
If I understand you right you need to insert the customer information in the stored procedure input variables then return the details for the newly inserted customer. In which case your INSERT for customer is right and instead of having an OUTPUT for the customer ID you need to SELECT the fields you want as in a normal select. The following should do what you want...
#Name varchar(50),
#Country int,
#DateRegistered datetime,
#NumberOfEmployees int
AS
DECLARE #ID INT -- moved this to be a standard variable
INSERT INTO AccountManagementChristian.dbo.Customer(Name, CountryID,
DateRegistered, EmployeeRangeID)
VALUES(#Name, #Country, #DateRegistered, #NumberOfEmployees)
SET #ID = ##IDENTITY
-- added this select to return the information you want,
-- using the #ID value to get details for the new customer
SELECT C.ID AS CustomerID, C.Name,
CL.ID AS CountryID, CL.CountryName,
ER.ID AS EmployeeRangeID, ER.NumberOfEmployees --, other fields required
FROM AccountManagementChristian.dbo.Customer AS C INNER JOIN
CountryLookup AS CL ON C.Country = CL.ID INNER JOIN
EmployeeRange AS ER ON C.EmployeeRangeID = ER.ID
WHERE C.ID = #ID
I am struggling to really understand where the "Insert Country return" option is coming in, since there is nothing here related to that. If you are, in fact, inserting the country and then using it, then just replicate the DECLARE #CustomerTab AND the OUTPUT INSERTED rows to catch that data. The updated script inserts the data and returns the fields I think you are asking for. Hope it helps. Below:
#Name varchar(50),
#Country int,
#DateRegistered datetime,
#NumberOfEmployees int,
#ID int output
AS
DECLARE #CustomerTab AS Table (CustomerID INT)
INSERT INTO AccountManagementChristian.dbo.Customer(Name, CountryID, DateRegistered, EmployeeRangeID)
OUTPUT
INSERTED.ID INTO #CustomerTab(CustomerId)
VALUES(#Name, #Country, #DateRegistered, #NumberOfEmployees)
--SET #ID = ##IDENTITY
select
Customer.Id
,Country.ID
,Country.[Country Name]
,EmployeeRange.[Number of Employees]
from
Customer
inner join
#CustomerTab CustomerTab
on
Customer.Id = CustomerTab.CustomerID
inner join
Country
on
Customer.CountryId = Country.Id
inner join
EmployeeRange
on
Customer.EmployeeRangeID = EmployeeRange.ID

Categories

Resources