Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Ошибка SQL-запроса  (Прочитано 7217 раз)

ARV

  • Постоялец
  • ***
  • Сообщений: 117
    • Просмотр профиля
Ошибка SQL-запроса
« : 09 Января 2025, 11:38:39 »
Почему возникает такая ошибка, как на скриншоте?
Запрос вроде бы корректный SHOW TABLES LIKE 'ut_%';, во всяком случае в MySQL Workbench выполняется без проблем (второй скриншот).

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3211
    • Просмотр профиля
    • Simple-Scada
Re: Ошибка SQL-запроса
« Ответ #1 : 10 Января 2025, 10:08:22 »
У нас с таким же запросом ошибок не возникает, результат тот же, что и в MySQLWorkbench.
Какая версия MySQL? Пришлите код скрипта которым выполняете запрос. Убедитесь, что ошибку даёт именно этот запрос, а не другой (например, вызванный через RunSQL в другом скрипте). Если создать новый проект только с этим запросом, то удаётся получить такой же результат?

ARV

  • Постоялец
  • ***
  • Сообщений: 117
    • Просмотр профиля
Re: Ошибка SQL-запроса
« Ответ #2 : 10 Января 2025, 15:30:51 »
Для удобства я написал такую функцию
Код: (delphi)
{ упрощенная реализация форматированного вывода
  fmt содержит подстановки:
  % - очередной аргумент (string, integer, boolean, single, double, extended)
  %% - процент
  формат вывода чисел по умолчанию (как в системе)
  если в массиве аргументов не хватает или больше, чем надо, ничего не происходит
  если в массиве неподдерживаемый аргумент, выводится знак вопроса
  использование:
    S := format('% % + % = %',['Результат', 1, 2, 1+2]);
    S = 'Результат 1 + 2 = 3';
}
function  format(const fmt : string; args : array of const) : string;
var
  position : integer;
  argpos : integer;
  Ch : string;
  V : Variant;
  S : string;
  VR : TVarRec;
  TS : string;
type TPS = ^string;
begin
  Result := '';
  position := 0;
  argpos := 0;

  while position <= length(fmt) do begin
    inc(position);
    Ch := fmt[position];
    if Ch <> '%' then begin
      // все, кроме %, копируется на выход
      Result := Result + Ch;
      continue;
    end;

    if position < length(fmt) then // добавлено 12.01.25: этой проверки не было, возможно, проблема с SQL была тут
    Ch := fmt[position+1];
    if Ch = '%' then begin
      // задвоенный % - это просто %
      Result := Result + '%';
      inc(position);
      continue;
    end else if argpos < length(args) then begin
      // поочередный вывод аргумента
      VR := args[argpos];
      inc(argpos);
      // в зависимости от типа аргумента
      case VR.VType of
      vtInteger     : S := IntToStr(VR.VInteger);
      vtBoolean     : if VR.VBoolean then S := 'true' else S := 'false';
      vtChar        : S := VR.VChar;
      vtExtended    : S := FloatToStr(VR.VExtended^);
      17 {!string!} : S := TPS(@args[argpos-1])^;
      else // неизвестно что
        S := '?';
      end;
      Result := Result + S;
    end;
  end;
end;
В ней всё прекрасно, кроме того, что "законными" средствами добраться до строки в массиве параметров невозможно, пришлось использовать грязный хак (см. пометку !string!). Не могли бы вы пояснить, почему обычный, то есть S := VR.VString^, не работает? И почему vtString в case тоже не даёт доступ к строке?

Предполагаю, что каким-то образом использование этой функции при построении запросов и влияло, но каким именно - не выяснил.
« Изменён: 15 Января 2025, 10:11:49 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3211
    • Просмотр профиля
    • Simple-Scada
Re: Ошибка SQL-запроса
« Ответ #3 : 13 Января 2025, 10:08:42 »
Цитировать
Предполагаю, что каким-то образом использование этой функции при построении запросов и влияло
Да, этот код будет приводить к ошибкам "access violation" и "invalid pointer operation" (либо незаметно портить память других переменных) если в массив параметров args будут передаваться строки, или символы (char, string, ansiString и т.п.). Судя по первым тестам проблема связана с неправильным подсчетом ссылок на строки в массиве аргументов. В результате он может привести к непредсказуемому поведению, поэтому в текущих версиях лучше отказаться от передачи открытого массива содержащего строки/символы. Если получится быстро добавить исправление, то включим его в ближайшее обновление, если нет, то как минимум временно уберём возможность передачи строк через открытый массив, чтобы исключить непредсказуемые ошибки.

ARV

  • Постоялец
  • ***
  • Сообщений: 117
    • Просмотр профиля
Re: Ошибка SQL-запроса
« Ответ #4 : 14 Января 2025, 12:41:17 »
Спасибо!

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3211
    • Просмотр профиля
    • Simple-Scada
Re: Ошибка SQL-запроса
« Ответ #5 : 05 Марта 2025, 10:50:38 »
В обновление 2.7.0.0 добавили передачу параметров через массив Variant (вместо открытого массива). Пример кода см. по ссылке.