IamLance1578 Ответов: 4

Общественные члены " к " тип "строка" ошибка


Это окно продолжает появляться всякий раз, когда я пытаюсь щелкнуть сетку данных, чтобы обновить информацию. Мне нужно обновить столбцы дат в моей таблице данных. Я использую SQLite и vb.net любая помощь будет оценена по достоинству.

Код в моем элементе управления DataGrid
Private Sub dgLogs_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgLogs.CellContentClick
    btnUpdate.Enabled = True

    Try
        txtLog.Text = dgLogs.Rows(e.RowIndex).Cells(0).Value.ToString
        dtpDateB.CustomFormat = dgLogs.Rows(e.RowIndex).Cells(1).Value.To("MM/dd/yyyy hh:mm")
        dtpDateR.CustomFormat = dgLogs.Rows(e.RowIndex).Cells(2).Value.To("MM/dd/yyyy hh:mm")
        txtLRN.Text = dgLogs.Rows(e.RowIndex).Cells(3).Value.ToString
        txtItem.Text = dgLogs.Rows(e.RowIndex).Cells(4).Value.ToString
    Catch ex As Exception
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
End Sub


Это код к моей кнопке обновления

Private Sub updateLogs()
        'UPDATE `tblLogs` SET `fldLog`=? WHERE _rowid_='13';
        strSQL = "UPDATE tblLogs SET fldDateB='" & dtpDateB.Text & "',
                                        fldDateR='" & dtpDateR.Text & "',
                                        fldLRN='" & txtLRN.Text & "',
                                        fldItem='" & txtItem.Text & "',
                                        WHERE fldLog='" & txtLog.Text & "'"
        Result = ExecNonQuery(strSQL)
        MessageBox.Show("Data has been updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information)
        Load_Data()
        initializeBtn()
    End Sub


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

Я попытался добавить ParseExact для даты, но я едва понимаю это.

Я также попытался изменить свойства для дат, например, изменить

...Эсэмэска кому .CustomFormat

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

Я тоже пробовал использовать .To("MM/dd/yyyy hh:mm), а не ToString, но он ничего не сделал

phil.o

Почему вы пытаетесь изменить формат строк ваших DateTimePickers каждый раз, когда щелкаете по ячейке? Вы понимаете, для чего нужна строка формата?

PIEBALDconsult

Вы хотите сказать, что код, который вы показываете, не является кодом, который производит заявленную ошибку?

IamLance1578

Я думаю, что это код. Ошибка появляется только тогда, когда я нажимаю на сетку данных.

4 Ответов

Рейтинг:
2

Richard MacCutchan

dtpDateB.CustomFormat = dgLogs.Rows(e.RowIndex).Cells(1).Value.To("MM/dd/yyyy hh:mm")

Класс String не содержит метода с именем To Используйте документацию, чтобы узнать, как создать форматированную дату.

И, пожалуйста, не используйте конкатенацию строк для создания операторов SQL. Используйте правильные параметризованные запросы с пользовательским вводом, который вы сначала проверяете.


Рейтинг:
2

OriginalGriff

Класс object не имеет свойства To или метода, поэтому система жалуется. Вполне возможно, что Тострунг сделает это, но ..... это какой-то очень странный код.
Вы устанавливаете формат DateTimePicker, когда кто - то нажимает на ячейку-это нормально, но если ячейка содержит строку формата, почему вы пытаетесь ее изменить? Разве это не противоречит цели? Попробуй:

dtpDateB.CustomFormat = dgLogs.Rows(e.RowIndex).Cells(1).Value.ToString
и посмотрим, сработает ли это.
Если это не так, то зачем вы вообще пытаетесь установить свойство CustomFormat?

И что еще более важно, почему вы объединяете строки для формирования команды SQL? Неужели ты не понимаешь, как это опасно?
Никогда не объединяйте строки для построения команды 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;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

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


Рейтинг:
2

Patrice T

strSQL = "UPDATE tblLogs SET fldDateB='" & dtpDateB.Text & "',
    fldDateR='" & dtpDateR.Text & "', fldLRN='" & txtLRN.Text & "',
    fldItem='" & txtItem.Text & "', WHERE fldLog='" & txtLog.Text & "'"

Не решение вашего вопроса, а еще одна проблема, которая у вас есть.
Никогда не создавайте SQL-запрос путем объединения строк. Рано или поздно вы сделаете это с помощью пользовательских вводов, и это откроет дверь к уязвимости под названием "SQL-инъекция", она опасна для вашей базы данных и подвержена ошибкам.
Одна кавычка в имени - и ваша программа выйдет из строя. Если пользователь вводит имя, например "Брайан О'Коннер", может привести к сбою вашего приложения, это уязвимость SQL-инъекции, и сбой-это наименьшая из проблем, вредоносный пользовательский ввод, и он продвигается к командам SQL со всеми учетными данными.
SQL-инъекция - Википедия[^]
SQL-инъекция[^]
Атаки SQL-инъекций на примере[^]
PHP: SQL-инъекция - руководство пользователя[^]
Шпаргалка по предотвращению инъекций SQL - OWASP[^]


Рейтинг:
1

phil.o

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

Прежде всего, как и в моем комментарии, Какой смысл менять формат вашей даты каждый раз, когда вы нажимаете на ячейку haas?

Во-вторых, как мы видим, Value собственность компании Cell объект имеет тип string. В зависимости от типа данных fldDateB и fldDateR столбцы в вашей базе данных, есть два решения:
- столбцы в базе данных имеют тип datetime: вы должны получить действительный DateTime ценность вне закона string хранится в столбце datagridview (см. ниже).
- столбцы в базе данных имеют тип varchar (n): вы можете сохранить значение как есть в базе данных. Но тогда у вас есть еще одна проблема: вы не используете правильный тип данных для хранения ваших данных. Как любил говорить один из моих учителей, просматривая коды наших новичков, если вы не используете правильный тип данных для данных, с которыми хотите работать, вы заслуживаете своих проблем.

Таким образом, существует несколько способов получить допустимое значение datetime из строки; Все лучшие из них подразумевают использование DateTime.Parse[^], DateTime.TryParse[^] и DateTime.TryParseExact[^] методы и их перегрузки.

Например, используя TryParseExact(string, string, IFormatProvider) метод, примененный к вашему случаю:

Dim dtb As DateTime = DateTime.TryParseExact(
   dgLogs.Rows(e.RowIndex).Cells(1).Value,
   "MM/dd/yyyy hh:mm",
   CultureInfo.CurrentCulture)

Dim dtr As DateTime = DateTime.TryParseExact(
   dgLogs.Rows(e.RowIndex).Cells(2).Value,
   "MM/dd/yyyy hh:mm",
   CultureInfo.CurrentCulture)

Когда вы делаете это, вы получаете действительные значения datetime в dtb и dtr переменные. Значения, которые затем можно ввести в базу данных.

Что подводит нас к последнему пункту, безусловно, самому важному из всех: никогда, ни в какой ситуации, не используйте сцепленные строки для построения SQL-запросов. Никогда. Только не делайте этого. Это оставляет ваш код открытым для атак SQL-инъекций, что является темой, которая рассматривается несколько раз в день на этом форуме.
Решение Гриффа говорит и об этом тоже. Пожалуйста, следуйте этому совету, он очень важен.