Delphi: FieldByName в сочетании с CURRENT_TIMESTAMP генерирует ошибку [FireDAC] [Phys] [MySQL] Таблица 'A' не была заблокирована с помощью LOCK TABLES - PullRequest
0 голосов
/ 09 июля 2020

Это мой первый вопрос. Искал по разным темам, но не нашел. Итак, здесь я go.

У меня запущена база данных MariaDB / MySQL. И добавил в таблицу поле: «AddedAt». Затем я обнаружил, что мой код Delphi (10.3) теперь генерирует ошибку в сочетании с LOCK TABLE. Мне нужно ЗАБЛОКИРОВАТЬ ТАБЛИЦУ, чтобы переупорядочить «ParagraphOrder», чтобы другие пользователи не делали то же самое в тот же момент.

Мой код был:

SQLString := 'LOCK TABLE ParOrder WRITE';
FDQuery1.ExecSQL (SQLString);

// Get all rows of project and document
SQLString := 'SELECT * ' +
             'FROM ParOrder ' +
             'ORDER BY ParagraphOrder DESC';
FDQuery1.Open(SQLString);
FDQuery1.First; // Point to first field.
OrderMax := FDQuery1.FieldByName('ParagraphOrder').AsInteger;
OrderMax := OrderMax * 2 + 10; // *2 + 10 is needed so the ParOrderValue as unique value.
while not FDQuery1.Eof do // loop
begin
  FDQuery1.Edit;
  FDQuery1.FieldByName('ParagraphOrder').AsString := (OrderMax).ToString;
  FDQuery1.Post;
  OrderMax := OrderMax - 2;
end;

Я использую MySQL базу данных (MariaDB) с таблицей:

CREATE TABLE `ParOrder ` (
    `ID` INT(11) NOT NULL AUTO_INCREMENT,
    `Number` CHAR(11) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
    `ParagraphOrder` INT(10) NOT NULL COMMENT 'Order of paragraphs',
    `AddedAt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`ID`) USING BTREE
)
COLLATE='utf8mb4_general_ci'
ENGINE=InnoDB;

«Проблема» находится в поле AddedAt, где я использую ON UPDATE CURRENT_TIMESTAMP. Это означает, что время и дата обновляются при обновлении записи. До того, как я добавил это поле, код работал. Теперь я получаю сообщение об ошибке: «[FireDAC] [Phys] [MySQL] Таблица« A »не была заблокирована с помощью LOCK TABLES»

Если я удалю поле «AddedAt», оно снова заработает. Моя работа заключается в использовании оператора SQL:

// Remove code
//FDQuery1.Edit;
//FDQuery1.FieldByName('ParagraphOrder').AsString := (OrderMax).ToString;
//FDQuery1.Post;
// Replace by:
  SQLString := 'UPDATE ParOrder ' +
               'SET ParagraphOrder = ' + (OrderMax).ToString + ' ' +
               'WHERE ID = ' + FDQuery1.FieldByName('ID').Text;
  FDQueryLocal := TFDQuery.Create(Self);
  FDQueryLocal.Connection := FDConnection1;
  FDQueryLocal.ExecSQL (SQLString);
  FDQueryLocal.Destroy;

Теперь мой вопрос: что я делаю не так? Почему FDQuery1.Post не работает, но выполняет весь оператор SQL?

Надеюсь, мне это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...