Задание: Код работает корректно, но при изменении значений ячейки появляется ошибка "Не удается найти строку для обновления. Некоторые значения могли быть изменены со времени ее последнего чтения". При это значения записываются в базу данных. Исправь эту ошибку.

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <Data.DB.hpp>
#include "Unit9.h"
#include <jpeg.hpp>
#include <pngimage.hpp>

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm9 *Form9;
using namespace std;



//---------------------------------------------------------------------------
__fastcall TForm9::TForm9(TComponent* Owner)
	: TForm(Owner)
{

}
//---------------------------------------------------------------------------
void __fastcall TForm9::FormCreate(TObject *Sender)
{
	// создание базы данных / таблицы, если их ещё не существует
	String s;
	s = "CREATE DATABASE IF NOT EXISTS `catalog`";
	ADOQuery1->SQL->Text = s;
	ADOQuery1->ExecSQL();
	s = "CREATE TABLE IF NOT EXISTS `catalog`.`products` (`ID` INT NOT NULL AUTO_INCREMENT, `name` VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL, `price` FLOAT(8, 2) NOT NULL, `description` TEXT CHARACTER SET utf8mb4 NOT NULL, `image` LONGBLOB NOT NULL, PRIMARY KEY (`ID`))";
	ADOQuery1->SQL->Text = s;
	ADOQuery1->ExecSQL();

	ADOQuery1->Close();
	ADOQuery1->SQL->Text = "SELECT * FROM `catalog`.`products`";
	ADOQuery1->Open();

	StringGrid1->RowCount = ADOQuery1->RecordCount + 1;
	StringGrid1->Cells[0][0] = "№";
	StringGrid1->Cells[1][0] = "Наименование";
	StringGrid1->Cells[2][0] = "Описание";
	StringGrid1->Cells[3][0] = "Стоимость";

	int row = 1;
	while (!ADOQuery1->Eof) {
		StringGrid1->Cells[0][row] = ADOQuery1->FieldByName("ID")->AsString;
		StringGrid1->Cells[1][row] = ADOQuery1->FieldByName("name")->AsString;
		StringGrid1->Cells[2][row] = ADOQuery1->FieldByName("description")->AsString;
		StringGrid1->Cells[3][row] = ADOQuery1->FieldByName("price")->AsString;
		row++;
		ADOQuery1->Next();
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm9::StringGrid1SelectCell(TObject *Sender, int ACol, int ARow,
		  bool &CanSelect)
{
	// Получение данных из столбца image таблицы
	ADOQuery1->RecNo = ARow;
	TMemoryStream *ms = new TMemoryStream();
	TBlobField *blob = dynamic_cast<TBlobField *>(ADOQuery1->FieldByName("image"));
	blob->SaveToStream(ms);
	ms->Position = 0;

	// Получение первых байт для определения типа изображения
    BYTE bytes[4];
	ms->ReadBuffer(bytes, 4);
    ms->Position = 0;

	// Сигнатура PNG: 137 80 78 71 (0x89 0x50 0x4E 0x47)
    if (bytes[0] == 0x89 && bytes[1] == 0x50 && bytes[2] == 0x4E && bytes[3] == 0x47)
    {
		TPngImage *png = new TPngImage;
        png->LoadFromStream(ms);
        Image1->Picture->Assign(png);
		delete png;
    }
    // Сигнатура JPEG: 255 216 (0xFF 0xD8)
	else if (bytes[0] == 0xFF && bytes[1] == 0xD8)
    {
		TJPEGImage *jpeg = new TJPEGImage;
        jpeg->LoadFromStream(ms);
		Image1->Picture->Assign(jpeg);
        delete jpeg;
	}
	// Отображение TImage на форме
	Image1->Visible = true;
	delete ms;
}

//---------------------------------------------------------------------------
void __fastcall TForm9::Button1Click(TObject *Sender)
{
	if (Edit1->Text.IsEmpty() || Edit2->Text.IsEmpty() || Memo1->Lines->Text.IsEmpty())
	{
		ShowMessage("Пожалуйста, заполните все поля!");
        return;
	}

    if (OpenPictureDialog1->FileName.IsEmpty())
    {
		ShowMessage("Пожалуйста, загрузите изображение!");
        return;
    }
try
{
	TFileStream *fs = new TFileStream(OpenPictureDialog1->FileName, fmOpenRead);
    try
    {
        // Указываем параметры для запроса
		ADOQuery1->SQL->Text = "INSERT INTO `catalog`.`products` (`name`, `price`, `description`, `image`) VALUES (:name, :price, :description, :image)";
		ADOQuery1->Parameters->ParamByName("name")->Value = Edit1->Text;
		ADOQuery1->Parameters->ParamByName("price")->Value = StrToFloat(Edit2->Text);
		ADOQuery1->Parameters->ParamByName("description")->Value = Memo1->Lines->Text;
		ADOQuery1->Parameters->ParamByName("name")->DataType = ftWideString;
		ADOQuery1->Parameters->ParamByName("description")->DataType = ftWideString;

        // Создаем поток для передачи изображения в базу данных
		TMemoryStream *stream = new TMemoryStream();
        try
		{
			stream->CopyFrom(fs, 0);
            stream->Position = 0;
            ADOQuery1->Parameters->ParamByName("image")->LoadFromStream(stream, ftBlob);

			ADOQuery1->ExecSQL();
		}
        __finally
        {
            delete stream;
        }
    }
	__finally
	{
		delete fs;
	}

    // Очистка полей ввода
	Edit1->Text="Название товара";
	Edit2->Text="0";
	Memo1->Lines->Text="Описание товара";

    // Очистка изображения
    Image2->Picture->Assign(NULL);

	// Обновление данных в таблице
    ADOQuery1->Close();
    ADOQuery1->SQL->Text = "SELECT * FROM `catalog`.`products`";
	ADOQuery1->Open();

}
catch (Exception &e)
{
    ShowMessage("Ошибка при добавлении товара: " + e.Message);
}

}
//---------------------------------------------------------------------------
void __fastcall TForm9::Button2Click(TObject *Sender)
{
	if (OpenPictureDialog1->Execute())
	{
		Image2->Picture->LoadFromFile(OpenPictureDialog1->FileName);
	}

}
//---------------------------------------------------------------------------
void __fastcall TForm9::StringGrid1SetEditText(TObject *Sender, int ACol, int ARow,
          const UnicodeString Value)
{
    if ((ARow >= 1) && (ARow <= ADOQuery1->RecordCount))
    {
        ADOQuery1->RecNo = ARow;
        TField* field = ADOQuery1->FindField("name");
        switch (ACol)
        {
            case 1:
                if (field)
                {
                    ADOQuery1->Edit();
                    field->AsString = Value;
                    ADOQuery1->Post();
                }
                break;
            case 2:
                field = ADOQuery1->FindField("description");
                if (field)
                {
                    ADOQuery1->Edit();
                    field->AsString = Value;
                    ADOQuery1->Post();
                }
                break;
            case 3:
                field = ADOQuery1->FindField("price");
                float price;
                if (TryStrToFloat(Value, price) && field)
                {
                    ADOQuery1->Edit();
                    field->AsFloat = price;
                    ADOQuery1->Post();
                }
                else
                {
                    ShowMessage("Некорректное значение цены");
                }
                break;
        }
    }
}