简体   繁体   English

.Net DateTime.Now vs PostgreSQL时间戳比较

[英].Net DateTime.Now vs PostgreSQL timestamp Comparison

Environment Mono, PostgreSQL, .Net MVC, Windows 环境Mono,PostgreSQL,.Net MVC,Windows

I'm try to show all events that occur in the future. 我试着展示将来发生的所有事件。

In order to do that I'm using the following SQL: 为了做到这一点,我使用以下SQL:

NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM dinners WHERE EventDate >= " + DateTime.Now, dinnerConn);

Now, if I compare DateTime.Now and my EventDate timestamp from the DB, I get the following 现在,如果我从DB中比较DateTime.Now和我的EventDate时间戳,我得到以下内容

(EventDate) 12/18/2010 7:00:00 PM - (DateTime.Now) 10/2/2010 7:59:48 PM

They seem pretty easily comparable to me, but whenever I run this query, I get the following: 它们看起来很容易与我相提并论,但每当我运行此查询时,我都会得到以下信息:

ERROR: 42601: syntax error at or near "8"

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: Npgsql.NpgsqlException: ERROR: 42601: syntax error at or near "8"

Source Error: 


Line 106:           try
Line 107:           {
Line 108:               NpgsqlDataReader reader = command.ExecuteReader();
Line 109:               while (reader.Read()) 
Line 110:               {

Source File: c:\Documents and Settings\Andrew\My Documents\Visual Studio 2008\Projects\MvcApplication1\MvcApplication1\Models\DBConnect.cs    Line: 108 

Now, I know the application works otherwise because if I ask it to pull all dinners, or all dinners greater than a specific ID, or a specific dinner, everything works fine, it just seems to be trying to compare timestamp to DateTime.Now. 现在,我知道该应用程序的工作原理是因为如果我要求它提取所有晚餐,或所有晚餐超过特定ID或特定晚餐,一切正常,它似乎只是试图将时间戳与DateTime.Now进行比较。

I know this is something simple. 我知道这很简单。 What am I doing wrong? 我究竟做错了什么?

This syntax should fix your problem: 此语法应该可以解决您的问题:

NpgsqlCommand sql = db.CreateCommand();
sql.CommandType = CommandType.Text;
sql.CommandText = @"SELECT * FROM dinners WHERE EventDate >= @eventdate ;";
sql.Parameters.Add("eventdate", NpgsqlType.Date).Values = DateTime.Now;

You consider to change your query ( reference ) so both timestamps are almost the same. 您考虑更改查询( 引用 ),以便两个时间戳几乎相同。

You're building a command as a string and not ensuring that the format the DateTime is serialised in is one that will be interpreted correctly by Postgres. 您正在将命令构建为字符串,而不是确保DateTime序列化的格式是Postgres将正确解释的格式。

You could use a consistent formatting by calling DateTime.ToString() with an appropriate format string. 您可以通过使用适当的格式字符串调用DateTime.ToString()来使用一致的格式。 For extra safety you could add the appropriate SQL to your string to make sure Postgres casts it explicitly to a date when reading the command, rather than depend upon implicit casting. 为了更加安全,您可以在字符串中添加适当的SQL,以确保Postgres在读取命令时将其显式转换为日期,而不是依赖于隐式转换。

However, Npgsql already has code to do this that is covered by its NUnit tests on every build. 但是,Npgsql已经有代码来执行此操作,并且每次构建时都会对其进行NUnit测试。 Much better to rely on that: 更好地依靠它:

NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM dinners WHERE EventDate >= :date", dinnerConn);
command.Parameters.Add(":date", DateTime.Now);

A final alternative is not to pass a DateTime from the .NET at all, but to use SELECT * FROM dinners WHERE EventDate >= now() . 最后一种选择是不要从.NET传递DateTime,而是使用SELECT * FROM dinners WHERE EventDate >= now() This way it will go by when the database considers to be the current date. 这样,当数据库认为是当前日期时,它将会过去。 There's a few minor advantages as far as optimisation of the connection goes, but the main reason for this is to maintain consistency between multiple callers into the same database. 就连接的优化而言,有一些小的优点,但主要原因是为了保持多个调用者之间在同一数据库中的一致性。 Having one place where "now" is defined (in this case the database machine) prevents potential issues with different machines being slightly out of synch. 在一个“now”定义的地方(在这种情况下是数据库机器)可以防止不同机器的潜在问题略微不同步。

The previous Add() method is now deprecated, use AddWithValue() : 现在不推荐使用以前的Add()方法,使用AddWithValue()

NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM dinners WHERE EventDate >= :date", dinnerConn);
command.Parameters.AddWithValue(":date", new NpgsqlTypes.NpgsqlDate(DateTime.Now));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM