我从事ASP.NET网页表单项目;我无法在datetime列中获取两个时间(时间开始和时间结束)之间的数据。
C#函数
public DataTable GetDataForSearch(string datelogged, string FromTime, string ToTime)
{
string response = string.Empty;
SqlCommand cmd = new SqlCommand();
DataTable dt = new DataTable();
try
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select datelogged AS EntredDatetime, Doc_type AS OrderType, Printer_name, BranchID AS BranchCode, Status, id from Print_Report where cast(datelogged as date)=@datelogged and and FORMAT(CAST(datelogged AS DATETIME), 'HH:mm')>'@FromTime' AND FORMAT(CAST(datelogged AS DATETIME), 'HH:mm')<@ToTime";
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 50000;
cmd.Parameters.AddWithValue("@datelogged", datelogged);
cmd.Parameters.AddWithValue("@FromTime", FromTime);
cmd.Parameters.AddWithValue("@ToTime", ToTime);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(dt);
}
catch (Exception ex)
{
response = ex.Message;
}
finally
{
cmd.Dispose();
conn.Close();
}
return dt;
}
当我从SQL Server尝试时,它返回2行:
select
datelogged as EntredDatetime, Doc_type as OrderType,
Printer_name, BranchID as BranchCode, Status, id
from
Print_Report
where
BranchID = '10207'
and cast(datelogged as date) = '2010-07-05'
and Doc_type = 'BP'
and format(cast(datelogged as DATETIME), 'HH:mm') > '13:30'
and format(cast(datelogged as DATETIME), 'HH:mm') < '14:00'
预期结果:
我将质询修改为:
cmd.CommandText = "select datelogged AS EntredDatetime, Doc_type AS OrderType, Printer_name, BranchID AS BranchCode, Status, id from Print_Report where BranchID=@BranchCode and cast(datelogged as date)=@datelogged and Doc_type=@OrderType and FORMAT(CAST(datelogged AS DATETIME), 'HH:mm')>='@FromTime' AND FORMAT(CAST(datelogged AS DATETIME), 'HH:mm')<='@ToTime'";
但仍然没有得到任何结果,所以我做什么来解决问题
2条答案
按热度按时间qlckcl4x1#
一定要声明你传递给SQL的参数类型,不要依赖sql来推断它,还要养成把你的数据库连接 Package 在
Using
块中的习惯。您还需要为@分支和@ordertype参数添加代码。
您的SQL将如下所示。在编写SQL时,大多数错误都可以通过在编写时一致地格式化SQL来管理。在声明param的数据类型时,参数不需要用引号括起来,就像我上面所做的那样。它会为您处理所有这些问题。而不是分别比较日期。我选择将时间作为Time数据类型传入,然后在查询中将其转换为datetime。您可以将两个日期时间与
+
相加,然后以相同的方式进行比较。如果您决定将您的传递给/从作为日期时间的值中删除顶部的声明行。您可以在
WHERE
子句中使用BETWEEN
,但这由您自行决定。pb3skfrl2#
所以,有几件事:
不要 Package 长代码行,它们很容易出错。
看看您的SQL,您会看到:
请注意,现在我们在SQL中看到"and and"是多么容易。
不要在SQL中执行这些强制转换,因为它很混乱,但是这样的表达式不能被索引,而且它们运行起来会非常慢。(此外,它使SQL变得相当混乱)。
下一步:考虑将内联SQL移到存储过程中,但更好的方法(更少的工作和精力)是使用视图,因此比存储过程"更少"工作,您可以使用查询构建器/设计器,更好的方法是多个例程可以使用一个"视图"。
接下来:
不要使用带值的加法-使用STRONG类型参数。
接下来:
在使用Parmaters时,Add("some parm","some value")被弃用,因为第二个参数可能会与作为dbtype的int混淆。
使用带"ADD"的类型化参数并不过时!!!,事实上我推荐使用
同样,上述格式并不过时,只有上述第二个参数为非dbtype的重载才过时!!!
接下来:
你没有显示连接对象是在哪里创建的。不要试图创建一些全局范围的连接对象。在"web时代"之前,为了性能,是的,我们经常"持久化"一个连接对象,但是对于基于web的,有一个自动的"连接"池,因此标准是每次重新创建连接,让系统自动为你处理。通过这样做,你在基于. netweb的系统中利用"自动"连接系统。
每次重新创建连接对象不会影响性能,因为连接池将"找到"并使用缓存的连接-它运行速度很快-您可以随时重新创建连接对象。
你如何让系统为你管理这个呢?为什么你总是用块来 Package 代码呢?在你的例子中,你只在代码错误时处理连接,而不是在成功时。
接下来:
如前所述,不要试图解析或转换SQL中的日期和日期时间,而是为开始日期和结束日期提供STRONG类型(都带有时间)。这样的代码不仅不那么混乱,而且代码中的工作量也很"小",但SQL变得非常非常混乱。因此,我们用"小"代码换取了漂亮干净的SQL的巨大好处。
所以,让我们吸取以上所有的教训,这样我们就得到了:
所以,请注意我们是如何让系统"关闭"连接的,并处理它的。即使代码出错,即使没有被捕获,连接和命令对象也会被正确地处理和管理-在所有情况下!!!
此外,请注意在代码端如何获得STRONG TYPED日期的开始和结束,从而使SQL部分的工作量大大减少,但更重要的是还意味着我们使用+享受STRONG类型的参数值,我们享受使用高速索引。