.Net DateTime.Now vs Сравнение меток времени PostgreSQL - PullRequest
3 голосов
/ 03 октября 2010

Окружающая среда Mono, PostgreSQL, .Net MVC, Windows

Я пытаюсь показать все события, которые произойдут в будущем.

Для этого я использую следующий SQL:

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

Теперь, если я сравню DateTime.Now и мою метку времени EventDate из БД, я получу следующее

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

Они кажутся довольно легко сопоставимыми со мной, но всякий раз, когда я запускаю этот запрос, я получаю следующее:

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 

Теперь я знаю, что приложение работает иначе, потому что, если я прошу его вытащить все обеды или все обеды, превышающие определенный ID, или конкретный обед, все работает нормально, просто кажется, что он пытается сравнить метку времени с DateTime .Теперь.

Я знаю, это что-то простое. Что я делаю не так?

Ответы [ 3 ]

6 голосов
/ 03 октября 2010

Этот синтаксис должен решить вашу проблему:

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;

Вы хотите изменить свой запрос ( ссылка ), чтобы обе метки времени были практически одинаковыми.

5 голосов
/ 03 октября 2010

Вы строите команду в виде строки и не гарантируете, что формат, в котором сериализуется DateTime, будет правильно интерпретирован Postgres.

Вы можете использовать согласованное форматирование, вызвав DateTime.ToString()с соответствующей строкой формата.В целях дополнительной безопасности вы можете добавить соответствующий SQL-код в строку, чтобы убедиться, что Postgres явно преобразует его в дату при чтении команды, а не зависит от неявного приведения.

Однако в Npgsql уже есть код, который делает это,покрывается тестами NUnit на каждой сборке.Намного лучше полагаться на это:

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

Последний вариант - вообще не передавать DateTime из .NET, а использовать SELECT * FROM dinners WHERE EventDate >= now().Таким образом, все пройдет, когда база данных будет считаться текущей датой.У оптимизации соединения есть несколько незначительных преимуществ, но главная причина этого заключается в том, чтобы поддерживать согласованность между несколькими абонентами в одной базе данных.Наличие одного места, где определено «сейчас» (в данном случае машина базы данных), предотвращает потенциальные проблемы, связанные с несовпадением различных машин.

0 голосов
/ 04 декабря 2018

Предыдущий метод Add() устарел, используйте AddWithValue():

NpgsqlCommand command = new NpgsqlCommand("SELECT * FROM dinners WHERE EventDate >= :date", dinnerConn);
command.Parameters.AddWithValue(":date", new NpgsqlTypes.NpgsqlDate(DateTime.Now));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...