На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Правила раздела C/C++: Базы данных
Модераторы: B.V.
  
    > Корректировка таблицы в базе на MySQL через компонент С++ TADOTable, Возникает ошибка "таблица не в EDIT или INSERT состоянии"
      У меня Windows XP и 7, MySQL 5.5.25 Win32, mysql-connector-odbe-5-1-6. Rad Studio C++ Builder 2010, База из дюжины таблиц.
      Связь с базой через компонент TADOConnection из набора dbGo, для получения данных использую компоненты TADOQuery, в параметре SQL которого помещаю запрос, комбинирующий данные нескольких таблиц базы, и компонент TDateSource из набора Data Access. Все ОК. Для формирования новых записей и корректировки старых пытаюсь использовать компонент TADOTable из того же набора dbGo, в котором создаю необходимые lookup поля и TDateSource. Не могу понять, почему в одном модуле программы корректировка по схеме
      BooksModule->ContractTbl->Active = true;
      if (BooksModule->ContractTbl->Locate("ContractKey",
      ObjectKey, SearchOptions))
      {
      BooksModule->ContractTbl->Edit();
      BooksModule->ContractTblFactTirage->Value +=
      BooksModule->EditionTblEditionTirage->Value;
      BooksModule->ContractTblBooksRecvd->Value +=
      BooksModule->EditionTblBookRecvd->Value;
      BooksModule->ContractTbl->Post();
      }

      выполняется без замечаний, тогда как в другом модуле той же программы и с той же таблицей ContractTbl, даже если между строками EDIT и POST убрать все строки корректировки, в строке POST возникает ошибка типа "Не могу определить нужную строку, так как в некоторые поля внесены изменения". При работе той же программы на базе Paradox 9 использовались только компоненты TTable и таких проблем не возникало. При создании новой записи в той же таблицы через состояние Insert компонента TADOTable проблем также не возникало. Очень не хочется писать SQL выражения для каждой корректировки таблиц базы.
      Мои вопросы:
      1. Можно ли корректировать MySQL таблицы изменяя данные в полях TADOTable, относящихся к той же таблице (свойство TablName компонента), (Lookup поля изменениями не затрагиваются) или для корректировки можно использовать только SQL выражения Update для компонента TADOQuery.
      2. Если можно, то с какими ограничениями?
        Цитата abtat @
        возникает ошибка типа "Не могу определить нужную строку, так как в некоторые поля внесены изменения"
        Первичный ключ есть?
          Первичный ключ - ContractKey, по нему Locate находит корректируемую запись и он до выполнения POST не меняется.
            Цитата abtat @
            он до выполнения POST не меняется.
            Первичный ключ не должен меняться НИКОГДА!
            Цитата abtat @
            для получения данных использую компоненты TADOQuery, в параметре SQL которого помещаю запрос, комбинирующий данные нескольких таблиц базы
            ОК! Выходит, что такое SQL - знаешь.
            Цитата abtat @
            Для формирования новых записей и корректировки старых пытаюсь использовать компонент TADOTable
            Забудь про табле НАВСЕГДА! Пользуйся для редактирования TADOQuery или TADOCommand.
            И учти, что если первый Query даёт выборку данных, то в него должен входить первичный ключ таблицы, в которой ты хочешь редактировать и этот ключ ты должен передать в Query/Command в параметре WHERE!
              Цитата abtat @
              "Не могу определить нужную строку, так как в некоторые поля внесены изменения"

              Курсоры в ADO
              Цель - ничто , процесс - все.
                Цитата #SI# @
                Цитата
                Забудь про табле НАВСЕГДА! Пользуйся для редактирования TADOQuery или TADOCommand.

                Я попробовал промоделировать ситуацию перехода с ХР на Win7 на малнькой тестовой программе, две процедуры из которой приведены ниже.

                //---------------------------------------------------------------------------
                void __fastcall TForm1::BookByAuthorBtnClick(TObject *Sender)
                {
                TADOQuery* ADOQuery1;
                ADOQuery1 = new TADOQuery(this);
                String SQL1 =
                "SELECT * FROM Book WHERE AuthorNbr = :ANbr";
                ADOQuery1->Connection = ADOConn;
                ADOQuery1->SQL->Clear();
                ADOQuery1->SQL->Add(SQL1);
                Param1 = ADOQuery1->Parameters->ParamByName("ANbr");
                Param1->DataType = ftSmallint;
                Param1->Value = StrToInt(AuthorKeyEdit->Text);
                ADOQuery1->Active = true;
                DataSrce2->DataSet = ADOQuery1;
                }

                //---------------------------------------------------------------------------
                void __fastcall TForm1::UpdBookBtnClick(TObject *Sender)
                {
                TADOQuery* ADOQuery2;
                ADOQuery2 = new TADOQuery(this);
                ADOQuery2->Connection = ADOConn;
                String SQL2 =
                "UPDATE Book \
                SET NbrOfEditions = :ENbr, Volume = :Vol \
                WHERE BookNbr = :BNbr2";
                ADOQuery2->SQL->Clear();
                ADOQuery2->SQL->Add(SQL2);
                Param3 = ADOQuery2->Parameters->ParamByName("ENbr");
                Param3->DataType = ftSmallint;
                Param3->Value = StrToInt(NbrOfEditionsEdit->Text);
                Param4 = ADOQuery2->Parameters->ParamByName("Vol");
                Param4->DataType = ftFloat;
                Param4->Value = StrToFloat(BookVolumeEdit->Text);
                Param5 = ADOQuery2->Parameters->ParamByName("BNbr2");
                Param5->DataType = ftSmallint;
                Param5->Value = StrToInt(BookKeyEdit->Text);
                ADOQuery2->Prepared = true;
                ADOQuery2->ExecSQL();
                }

                Таблица Book была создана следующим SQL скриптом:

                CREATE TABLE `book` (
                `BookNbr` SMALLINT(6) NOT NULL AUTO_INCREMENT,
                `BookName` VARCHAR(50) COLLATE utf8_general_ci DEFAULT NULL,
                `AuthorNbr` SMALLINT(6) DEFAULT NULL,
                `Volume` DECIMAL(5,2) DEFAULT NULL,
                `FirstPub` SMALLINT(6) UNSIGNED DEFAULT NULL,
                `NbrOfEditions` SMALLINT(6) DEFAULT NULL,
                `Comment` VARCHAR(60) COLLATE utf8_general_ci DEFAULT NULL,
                PRIMARY KEY (`BookNbr`) COMMENT ''
                )ENGINE=InnoDB

                Запросы были написаны в соответствие с рекомендациями из статьи
                ms-help://embatcadero.rs2010/codesamples/ADOQuery_(C++).html и при работе в Windows XP все работало без аномалий.
                После переноса задачи на машину с Windows 7, оба запроса выполняются правильно, но, по крайней мере, в половине случаев при исполнении каждого запроса происходит остановка и выдается сообщение класса EOleException: «Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом». Если в окне сообщения нажать кнопку “Continue”, то запрос выполняется и его результат правильный. Это означает, что аргументы имели правильное значение, а сообщение об ошибке было ложным Даже при повторении запроса без изменения аргументов остановки то происходят, то нет. В этой же среде Windows XP компиляция очень большой С++ Builder программы и ее исполнение при работе с той же базой при работе с данными через компоненту TADOTable происходят без аномалий. Что бы это могло означать и как от такой остановки избавиться?
                У меня Windows 7 (32 bit), MySQL 5.5.25 и MySQL ODBC Connector 5.3.4-Win32
                Сообщение отредактировано: abtat -
                  Цитата abtat @
                  Я попробовал промоделировать ситуацию перехода с ХР на Win7
                  Я с ХР переехал на семёрку, а потом и на восьмёрку без всякого моделирования. Это первое.
                  Второе - научись пользоваться кнопкой CODE. Третье - накой ляд ты динамически создаёшь компоненты? Четвёртое - с параметрами просто кошмар! Для ТВОИХ данных они вообще не нужны!
                  Цитата abtat @
                  Аргументы имеют неверный тип, выходят за пределы допустимого диапазона или вступают в конфликт друг с другом
                  Телепаты в отпуске - что ты на самом деле туда подставлял, никому, кроме тебя, неведомо.
                    Цитата #SI# @
                    - накой ляд ты динамически создаёшь компоненты?

                    Я пробовал и статические и и динамические.
                    Я думаю, что ты уж зря зубоскалишь.
                    Цитата #SI# @
                    Второе - научись пользоваться кнопкой CODE.

                    Лишние Тэги пихать в мой текст сообщения я смысла не вижу.
                    Цитата #SI# @
                    - с параметрами просто кошмар! Для ТВОИХ данных они вообще не нужны!

                    Если ты предложишь, как править разные записи в таблице СУБД без использования параметров, честь тебе и хвала. я о таком не слышал. С использованием статических компонент параметры нужны не менее.
                    Цитата #SI# @
                    Телепаты в отпуске - что ты на самом деле туда подставлял, никому, кроме тебя, неведомо.

                    Если я создал в таблице колонку smallint то можно предположить, что выбираю я для аргументов небольшие числа. В моем эксперимента - от 1 до 10. Для колонки DECIMAL(5,2) выбирались числа до 10 с 2 дробными знаками. Кстати, я написал, что результаты всех выполнений каждого из двух представленных запросов получались правильными, хотя иногда и после сообщения об ошибке и ответа "Continue", значит аргументы были соответствующие структуре таблицы. Ты мог бы это предположить.
                    Так что, кончай хохмить! Если есть дельные мысли. я их с радостью прочитаю, если их нет, то зачем отвечать.
                      Цитата abtat @
                      Лишние Тэги пихать в мой текст сообщения я смысла не вижу
                      Правила читай. А по поводу всего остального - не вижу смысла продолжать дискуссию. :whistle: Извиняй, если что...
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script Execution time: 0,1090 ]   [ 18 queries used ]   [ Generated: 26.09.17, 20:04 GMT ]