kyrons Ответов: 1

Как определить, что одно значение поля даты позже/больше, чем другое поле даты?


У меня есть одно текстовое поле(отображает результат подсчета), одна кнопка(выполняет подсчет) и два DateTimePickers(для периода дат от и до) в форме. Я использую базу данных MS Access для своей программы с двумя полями дат(date1 и date2). Что я хочу, так это подсчитать, сколько записей датировано(даты даны из datetimepickerfrom и datetimepickerto). Подсчет ведется с условием типа: Если date2 больше или позже date1, то подсчет будет основываться на date2, иначе на date1. Любое предложение или изменение в моем коде высоко ценится.

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

Это мой код, но он приводит к ошибке:"элемент не может быть найден в коллекции, соответствующей запрошенному имени или порядковому номеру."

 countingconnection()
        countrec = New ADODB.Recordset
        With countrec

 If .Fields("Date2").Value > .Fields("Date1").Value Then
    .Open("select count(*) as count2 from Docstable where Date2 >=#" & DateTimePickerfrom.Value.Date & "# and Date2 <=#" & DateTimePickerto.Value.Date & "#", countcon, 2, 3)
            textbox1.Text = .Fields("count2").Value
            .Close()
else
       .Open("select count(*) as count1 from Docstable where Date1 >=#" & DateTimePickerfrom.Value.Date & "# and Date1 <=#" & DateTimePickerto.Value.Date & "#", countcon, 2, 3)
            textbox1.Text = .Fields("count1").Value
            .Close()
        
end if
   


        End With

Richard Deeming

Почему вы все еще используете давно умершую библиотеку ADODB в приложении .NET? ADO.NET он существует уже почти 20 лет и гораздо лучше и проще в использовании.

Вы также должны использовать параметры, а не пытаться вставить значения параметров непосредственно в строку запроса. В данном конкретном случае вы, вероятно, в порядке, но использование конкатенации строк может и приведет к SQL-инъекция[^] факторы уязвимости.

1 Ответов

Рейтинг:
2

OriginalGriff

Не делай этого. Никогда не объединяйте строки для построения команды SQL. Это оставляет вас широко открытыми для случайной или преднамеренной атаки SQL-инъекции, которая может уничтожить всю вашу базу данных. Вместо этого всегда используйте параметризованные запросы.

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:

SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?

Хотя ваш фрагмент кода напрямую не подвергает вас SQL - инъекции, он подвергает вас другим проблемам-например, сервер БД не использует тот же формат даты по умолчанию, что и ваше приложение, и в этот момент вы начинаете получать периодические проблемы: сбои приложений, неверные данные, вы знаете, что это такое.
Передайте даты как DateTime непосредственно в качестве параметров вместо преобразования их в строки, и эти проблемы исчезнут.

Кстати: вы также можете использовать SQL BETWEEN для сравнения:
... WHILE @DateToCompare BETWEEN Date1 AND Date2

Но проверьте остальную часть вашего приложения и замените любую конкатенацию параметрами!