I am trying to pass a null Date parameter to SQL stored procedure from C#. If I run the stored procedure directly, I get values in the total column:
However, if I call the stored procedure from my C# code and pass null Date parameter, the Total column for all rows returns Zero (0):
I set the date parameters in the stored procedure if the date parameter is null, so it returns the correct records just no totals.
Here is my stored procedure code:
DECLARE @StartDate date= null, @EndDate date = null
If(@StartDate IS NULL) SET @StartDate = getDate()-30;
If(@EndDate is NULL) SET @EndDate = getDate();
WITH
L0 AS ( SELECT 1 AS c
FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),
(1),(1),(1),(1),(1),(1),(1),(1)) AS D(c) ),
L1 AS ( SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B ),
L2 AS ( SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B ),
Nums AS ( SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum
FROM L2 ),
Date_Range_T (d_range) AS (
SELECT TOP(DATEDIFF(day, @StartDate, @EndDate) + 1)
DATEADD(day, rownum - 1, @StartDate) AS d_range
FROM Nums
)
SELECT CONVERT(VARCHAR, d_range, 101) AS CreateDate, COUNT(R.Id) AS Total
FROM Date_Range_T
LEFT JOIN tbl_Support_Requests R ON Cast(R.CreatedDate as date) = d_range
LEFT JOIN dbo.tbl_Employee_Companies ec on ec.Id = R.ReporterId
GROUP BY d_range
ORDER BY d_range ASC
OPTION (MAXRECURSION 366);
Here is my C# method:
public List<ChartData> GetSupportTicketMetrics_ByDateRange(string startDate, string endDate)
{
DateTime? StartDate = null;
DateTime? EndDate = null;
if (startDate != "")
{
StartDate = Convert.ToDateTime(startDate);
}
if (endDate != "")
{
EndDate = Convert.ToDateTime(endDate);
}
var list = new List<ChartData>();
var sql = "exec stp_GetSupportTicketMetrics_ByDateRange {0}, {1};";
try
{
using (var sdb = new SafetyDataContext())
{
list = sdb.ExecuteQueryNullSafe<ChartData>(sql, StartDate, EndDate).ToList();
}
}
catch (Exception e)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(e);
string msg = e.Message;
}
return list;
}
Here is ExecuteQueryNullSafe:
internal static IEnumerable<TResult> ExecuteQueryNullSafe<TResult>(this System.Data.Linq.DataContext context,
string command, params object[] parameters)
{
var list = new List<object>();
var listVals = new List<bool>();
for (int x = 0; x < parameters.Count(); x++)
{
if (parameters[x] == null || parameters[x] is System.DBNull)
{
command = command.Replace("{" + x + "}", "NULL");
listVals.Add(false);
}
else
{
list.Add(parameters[x]);
listVals.Add(true);
}
}
int nextId = 0;
for (int i = 0; i < listVals.Count; i++)
{
var isUsed = listVals[i];
if (!isUsed)
continue;
if (nextId != i)
command = command.Replace("{" + i.ToString() + "}", "{" + nextId.ToString() + "}");
nextId++;
}
return context.ExecuteQuery<TResult>(command, list.ToArray());
}
Now if I actually supply the exact same dates to the method, the list returned has values in the Total column. I can't figure out why the query runs as it in SQL but doesn't supply the values when called from C# code.