views:

846

answers:

3

I am getting this error on a remote server, but the same code executes fine locally. Please refrain from saying it sucks, or giving me your rant on dynamic sql, I didn't write it, just trying to figure out why it's throwing an exception. The highlighted error is line 56.

Protected Sub drpDateRange_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles drpRange.SelectedIndexChanged
    Dim sql As String = "SELECT postedDate, inspectionType FROM tInspectionRequest WHERE source_lookupID = 'IRS_WEB' "
    If _franchiseID > 0 Then sql &= " and franchiseeID = " & _franchiseID.ToString
    Dim db As New Database
    Dim ds As DataSet = db.selectQuery(sql)
    Dim dv As New DataView(ds.Tables(0))
    dv.RowFilter = "inspectionType='Buyer' AND postedDate >= #" & DateTime.Now.AddDays(-1) & "#"
    lblB1.Text = dv.Count
End Sub

Here is the exception, it seems like DateTime.Now.AddDays(-1) is failing being cast as a datetime? Regardless if it's a casting issue / date to string error, it's strange it fails only on the remote server, and not locally.

String was not recognized as a valid DateTime. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.FormatException: String was not recognized as a valid DateTime.

Source Error:

Line 55: Dim dsInspectionHistory As DataSet = objDB.selectQuery(sqlInspectionHistory)

Line 56: Dim dvInspectionHistory As New DataView(dsInspectionHistory.Tables(0))

Line 57: dvInspectionHistory.RowFilter = "inspectionType='Buyer' AND postedDate >= #" & DateTime.Now.AddDays(-1).ToString & "#"

Line 58: lblB1.Text = dvInspectionHistory.Count

Line 59: dvInspectionHistory.RowFilter = "inspectionType='Seller' AND postedDate >= #" & DateTime.Now.AddDays(-1) & "#"

[FormatException: String was not recognized as a valid DateTime.] System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles) +2291962 System.DateTime.Parse(String s, IFormatProvider provider) +26 System.Data.ConstNode..ctor(DataTable table, ValueType type, Object constant, Boolean fParseQuotes) +485 System.Data.ExpressionParser.Parse() +830 System.Data.DataExpression..ctor(DataTable table, String expression, Type type) +124 System.Data.DataView.set_RowFilter(String value) +161 controls_inspectionRequestChart.drpRange_SelectedIndexChanged(Object sender, EventArgs e) in xxxx controls_inspectionRequestChart.Page_Load(Object sender, EventArgs e) in xxxx System.Web.UI.Control.OnPreRender(EventArgs e) +2117788 System.Web.UI.Control.PreRenderRecursiveInternal() +86 System.Web.UI.Control.PreRenderRecursiveInternal() +170 System.Web.UI.Control.PreRenderRecursiveInternal() +170 System.Web.UI.Control.PreRenderRecursiveInternal() +170 System.Web.UI.Control.PreRenderRecursiveInternal() +170 System.Web.UI.Control.PreRenderRecursiveInternal() +170 System.Web.UI.Control.PreRenderRecursiveInternal() +170 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2041

A: 

Whats with the #'s surrounding the date?

SQL understands quoted dates when using text represented dates, ie '01/01/1901' or '05/28/1978 21:13:00.000'.

The dataset/table you are selecting from may have the postedDate column as a String and not a DateTime. Can you check the column type?

Check the regional settings on the remote machine and see if they match your regional settings.

StingyJack
that line doesn't go to SQL, its actually querying built into system.dataview, that im not very familiar with
Shawn Simon
i bet you're right. i bet the database types are different. let me check
Shawn Simon
Its hitting the data that was returned from SQL, and that may not be stored as the type you expect.
StingyJack
The # is a convention used in vb and Access for date literals that sql server is normally happy to accept
Joel Coehoorn
nope, datetime on both : <this code worked about a week ago too, i have no idea what happened
Shawn Simon
I've not done a DataView.RowFilter before, I usually use DataTable.Select(). That may work for you also.
StingyJack
+6  A: 

This might be due to a regional datetime settings difference between the server and your dev PC. There is an implicit conversion between datetime and string in the code (remember it is inline sql (Edit: RowFilter syntax), you're not setting a parameter).

Try formatting the string

dv.RowFilter = "inspectionType='Buyer' AND postedDate >= #" & DateTime.Now.AddDays(-1).ToString("MMM dd yyyy hh.mm.ss") & "#"
Christopher Edwards
It's not inline Sql, but RowFilter syntax: http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression(vs.71).aspxThat said, I'm betting it's regional settings as well, so +1.
Mark Brackett
Your format string needs double quotes, but otherwise I think this is likely to solve the problem.
Joel Coehoorn
@Mark, you are correct, I'll check the RorFilter syntax is the same then edit the post.
Christopher Edwards
@Coehoorn, you are correct, I had it in my head somehow that I needed to worry about escaping, but I don't at all, I'll edit it.
Christopher Edwards
DateTime.Now.AddDays(-1).ToLongTimeString worked. jsut remembered my coworked killed the web.config which must have changed the regional settings. thanks!!!
Shawn Simon
One more thing: I'd use string.Format(), like this: dv.RowFilter = String.Format("inspectionType='Buyer' AND postedDate >= #{0}#", DateTime.Now.AddDays(-1).ToString("MMM dd yyyy hh.mm.ss"))
Joel Coehoorn
+2  A: 

I think ChrisE's answer is likely to solve your problem, but while you're fixing it why not actually fix it.

Protected Sub drpDateRange_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles drpRange.SelectedIndexChanged
    Dim sql As String
    sql = "DECLARE @Yesterday DateTime;Set @Yesterday= getdate()-1;" & _
      " SELECT COUNT(*) AS CNT" & _
      " FROM tInspectionRequest" & _
      " WHERE source_lookupID = 'IRS_WEB' AND inspectionType='Buyer'" & _
          " AND (@FranchiseID <= 0 OR @FranchiseID = franchiseID)" & _
          " AND postedDate >= @Yesterday;"
     lblB1.Text = New Database().selectQuery(sql.Replace("@FranchiseID", _franchiseID.ToString()))
End Sub

This should perform much better because it lets the database handle filtering the rows and only sends the necessary information across the connection. It also completely side-steps your date conversion problem by letting the database handle that for you.

Of course real query parameters would be even better, but I understand you can't do that yet because you have to use that custom database wrapper and it's not a big deal here because the only parameter is a strongly-typed integer. Also, I don't know what provision if any the database wrapper makes for returning a scalar value rather than a dataset. There ought to be something, but it means you'll need to at least change that function name for this code to work.

Joel Coehoorn
i cut out a lot of code, it actualyl does a lot more in there, thank you though
Shawn Simon
Well if you actually use the dataset than it might be important. But I suspect you could still do better by at least adding the dataview filter directly to the query.
Joel Coehoorn