构建具有日期值的 SelectCommand

Building A SelectCommand with a Date Value

我正致力于在 ASP.NET/ C# WebForms 中构建查询。查询依赖于一系列if语句如下:

//start building the query, I know SID will always be defined:
string firstpart = "SELECT * FROM [ExampleTable] WHERE StudentID= @SID";

//the variable student name is a URL variable. All the other URL variables follow this logic, 9 potential variables in total, so 9 if statements in total.
if (studentname != "") {
    dsResults.SelectParameters.Add("sname", studentname.ToString());
    secondpart = " AND UPPER(StudentName) LIKE UPPER('%' + @sname+ '%')";
}
else{
    //if URL variable is empty, simply make the string empty so it is ignored.
    secondpart = "";
}

最后,我将它们全部添加到我用来构建查询的字符串中:

entirecommand = firstpart + secondpart + thirdpart + fourthpart + fifthpart + sixthpart + seventhpart + eighthpart + ninthpart + " ORDER BY [StudentID]";

最后,我设置

dsResults.SelectCommand = entirecommand;

执行查询,结果数据绑定到gridview如下:

if (!Page.IsPostBack){
    //bind the gridview data
    gvResults.DataSource = dsResults;
    gvResults.DataBind();
}

在我尝试向查询中添加日期之前,一切都运行得很完美

if  (sSDate != ""){
    dsResults.SelectParameters.Add("startdate", sSDate.ToString());
    ninthpart = " AND DateEntered > '%' + @startdate + '%'";
}

当我尝试这样做时,我收到错误 'Conversion failed when converting date and/or time from character string.' 在线:

gvResults.DataBind();

我把日期部分写在了第九部分,所以最后才加上。正如我所说,如果没有将第九部分添加到字符串中,一切都会按预期进行。

郑重声明,我的日期格式为 URL:yyyy-mm-dd。只查找大于该日期的日期,根本不关心时间。

我真的不知道这个应该去哪里,所以如果有人有什么建议,请告诉我。我对 ASP.Net 还是很陌生,所以如果有更好的方法来完成我想要完成的事情,或者如果您需要更多信息,请告诉我!

编辑

感谢大家的帮助!我现在可以让它工作了!我的大问题是查询字符串中日期周围的百分比符号。我删除了那些,并更改了我第一次从 URL 设置日期的数据类型(最初是字符串,但更改为日期时间。然后我从每次添加中删除了 .toString() 部分,因为它们不需要(它们最初设置为字符串,除了日期,我不想将其转换为字符串)。在这些更改之后,它提供了所需的结果,并与查询字符串的其余部分一起使用。你的建议非常宝贵,我怎么说都不谢谢你!

首先,几乎所有数据库系统使用的日期格式都是内部日期格式。外部日期格式和计算机的区域设置当然会导致此格式发生变化,或者通常您甚至不知道!

在sql服务器中,日期格式应该是ISO。即 YYYY-MM-DD。而且您不要用 % 包围日期。您用单引号将日期括起来。

而且你不应该使用一些 DateVar.ToString。原因当然是在这种情况下吐出的日期将基于用户的日期设置——但你不希望这样。

所以,你的代码应该是这样的:

if  (sSDate != ""){
    dsResults.SelectParameters.Add("@startdate", DbType.Date, sSDate.ToString("YYYY-MM-dd"));
    ninthpart = " AND DateEntered > @startdate ";
}

以上假定 SQL 服务器 - 但也适用于 MS-access。因此,您 need/want/should 将日期格式强制为 sql 服务器等将接受的标准格式。 (您不想使用或让用户的系统默认设置转换为字符串 - 否则您可能会得到一个翻转月份和日期的日期字符串。

例如:

MM/DD/YYYY

DD/MM/YYYY

因为我们有

2020 年 5 月 10 日

那是 5 月 10 日,还是 10 月 5 日?那么,您获得的字符串将取决于用户的日期设置!!!

所以,这就是为什么您总是希望将日期输出字符串强制为已知的标准格式 - 而不是用户设置的格式。只要该变量是日期,或声明为日期时间变量,那么上面的内容应该没问题。

哪里会出现困难取决于用户输入的文本框。您应该将其强制为日期控件 - 因此该控件的结果将是真正的日期数据类型。 因此,假设 Web 表单上的控件设置为最新,那么您会看到:

然后在代码中,将结果推送到实际日期或日期时间变量中。

dim dtMyDate as date

dim dtMyDAte as datetime

then - dtMyDate = MyDateTextBox.Text

then use above and the tostring as a formatted ISO sql server date string.

在这段代码中,您有很大的误解,认为您将日期作为字符串进行操作

if  (sSDate != "")
{
    dsResults.SelectParameters.Add("startdate", sSDate.ToString());
    ninthpart = " AND DateEntered > '%' + @startdate + '%'";
}

如果sDate是从用户输入的字符串格式中检索出来的,您需要对其进行转换。您可以使用任何或 Convert.ToDateTime, DateTime.Parse, DateTime.TryParse 等。您需要将日期作为 DateTime 传递。在查询中,将日期视为参数化 date。不要将其转换为字符串。您的代码应该类似于

if  (DateTime.TryParse(sSDate, out DateTime myDate))
{
    
    dsResults.SelectParameters.Add("@startdate", myDate);  //<--
    ninthpart = " AND DateEntered > @startdate"; //<--
}

现在这在所有方面都很好。