Member 11291660 Ответов: 1

Как фильтровать данные между двумя диапазонами дат из базы данных ms access с помощью C#


Выбор даты из столбца DateTime базы данных ms access показывает "No Record Found".
Подключение к datbase осуществляется с помощью "Microsoft.ACE.OLEDB.12.0", а передний конец-VS C#

Что я уже пробовал:

connectionstring — ImgBB[^]
db — ImgBB[^]
форма — ImgBB[^]
запрос — ImgBB[^]


  con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=F:\\xxxxxxx\\yyyyy\\zzzzz\\database.accdb;Persist Security Info=True;Jet OLEDB:Database Password=xyz";
            if (con.State != ConnectionState.Open)
            {
                con.Open();
            }
        
 DateTime fromdate = Convert.ToDateTime(dtpfdt.Value.ToString("dd-MMM-yyyy") + " 00:00:00 AM");
                    DateTime todate = Convert.ToDateTime(dtptodt.Value.AddDays(1.0).ToString("dd-MMM-yyyy") + " 00:00:00 AM").AddSeconds(-1.0);
                string query = "SELECT * FROM [TRANSACTION] WHERE ([DT1] BETWEEN #" + fromdate + "# AND #" + todate + "#) OR ([DT2] BETWEEN #" + fromdate + "# AND #" + todate + "#)";
-----------;
----------;
--
.
.
.


dtpfdt==> Datetime Picker(From date)
dtpto==> Datetime Picker(To date)
[TRANSACTION]--- Table
[WT1]--- Column; Type--> Date/Time    Format--> General Date
[WT2]--- Column; Type--> Date/Time    Format--> General Date



объект DataTable
+---------------------+----------------------+
|      DT1            |         DT2          |
+--------------------------------------------+
| 24-04-20 1:38:35 AM | 25-04-20 1:41:35 AM  |
+---------------------+----------------------+
| 24-04-20 1:39:27 AM | 25-04-20 1:42:11 AM  |
+---------------------+----------------------+
| 25-04-20 1:40:22 AM | 25-04-20 1:42:39 AM  |
+---------------------+----------------------+



Я уже пробовал >= и <= условие вместо 'BETWEEN- и изменил формат datetime столбца данных datatime и выбора даты и времени, а также системных часов, но ничего не работает.
Что-нибудь не так в моем кодировании?
Пожалуйста, посоветуйте мне исправить мои ошибки.
Спасибо.

1 Ответов

Рейтинг:
10

Maciej Los

string query = "SELECT * FROM [TRANSACTION] WHERE ([DT1] BETWEEN #" + fromdate + "# AND #" + todate + "#) OR ([DT2] BETWEEN #" + fromdate + "# AND #" + todate + "#)";

Такой запрос есть SqlInjection[^] уязвимый!

Вместо этого используйте параметризованный запрос:
string query = "SELECT * FROM [TRANSACTION] WHERE (([DT1] BETWEEN ? AND ?) OR ([DT2] BETWEEN ? AND ?));";


Использование:
	string sConn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=YourDatabase.accdb;Persist Security Info =False;";
	DataTable dt = new DataTable();

	DateTime fromdate = DateTimePickerDateFrom.Value;
	DateTime todate = DateTimePickerDateTo.Value;
	string sComm = "SELECT * FROM [TRANSACTION] WHERE (([DT1] BETWEEN ? AND ?) OR ([DT2] BETWEEN ? AND ?));";

	using (OleDbConnection oConn = new OleDbConnection(sConn))
		{
			oConn.Open();
			using (OleDbCommand oComm  = new OleDbCommand(sComm, oConn))
			{ //first part of Where condition
				oComm.Parameters.Add(new OleDbParameter(){Value=fromdate, OleDbType = OleDbType.DBTimeStamp ;});
				oComm.Parameters.Add(new OleDbParameter(){Value=todate, OleDbType = OleDbType.DBTimeStamp ;});
				//second part of Where condition
				oComm.Parameters.Add(new OleDbParameter(){Value=fromdate, OleDbType = OleDbType.DBTimeStamp ;});
				oComm.Parameters.Add(new OleDbParameter(){Value=todate, OleDbType = OleDbType.DBTimeStamp ;});				using (OleDbDataReader oRdr = oComm.ExecuteReader())
				{
					dt.Load(oRdr);
				}
			}
		}

if(dt.Rows.Count==0)
//no data!
else
//use can use data from dt ;)


Примечание: поставщик OleDb для MS Access database engine не поддерживает именованные параметры! Таким образом, вы должны добавить столько параметров, сколько используется в запросе. Порядок добавления параметров к SqlParametersCollection это очень важно!


Member 11291660

Спасибо Мацей Лос,
Я попробовал ваше предложение.
ExecuteReader()--> показывает "несоответствие типов данных в выражении критериев"

Maciej Los

Похоже, ваша исходная таблица использует имя поля WT1 вместо DT1. Итак, измените запрос соответствующим образом.

Примечание: Я тестировал подобный код в своей базе данных. И это прекрасно работает!

Maciej Los

Смотрите обновленный ответ!

Member 11291660

Г-Н Мацей Лос

Большое спасибо за вашу доброту. Я действительно застрял на последние 4 дня, Что касается этого вопроса. С помощью вашего доброго руководства ,теперь мой код работает безупречно. Я просто немного изменил код, который вы предложили.


Рабочий код таков:
----------------------------------------------------------
DateTime fromdate = конвертировать.Объект todatetime(dtpfdt.Значение.ToString("dd-MMM-yyyy") + " 00:00:00 AM");
DateTime todate = конвертировать.Объект todatetime(dtptodt.Значение.AddDays(1.0).ToString("dd-MMM-yyyy") + "00:00:00 AM").AddSeconds(-1.0);
запрос = "выбрать * из [Сделка], где (([СТ1] между @dtfrom и @dtto) или ([ст2] между @dtfrom и @dtto));";
OleDbConnection oConn = new OleDbConnection(con.ConnectionString);
oConn.Открыть();
OleDbCommand oComm = new OleDbCommand(query, oConn);
окомм.параметры.Add(new OleDbParameter("@dtfrom",fromdate.Метод toString()));
окомм.параметры.Add(new OleDbParameter("@dtto",todate.Метод toString()));
И oledbdatareader oRdr = осоммбыл.Метода executereader();
dt.нагрузка(oRdr);
---------------------------------------------------------
раз спасибо.

Maciej Los

Вы должны использовать using заявление, как я вам показывал! Это настоятельно рекомендуется!

Member 11291660

Я не силен в программировании. Позвольте мне узнать, как важно использовать утверждение. Без оператора using он, кажется, работает правильно, вот почему я спрашиваю.

Спасибо Господин Мацей Лос

Member 11291660

Понял.
Спасибо Господин Мацей Лос

Maciej Los

Всегда пожалуйста.

0x01AA

+5

Maciej Los

Спасибо, Бруно.

BillWoodruff

+5

Maciej Los

- Спасибо, Билл.