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

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

Автор Тема: В строке произвольно появляется мусор  (Прочитано 3761 раз)

dima_k

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
по нажатию клавиши выполняется процедура:
Код: (delphi)
var q : string;
begin
  if Sender.Tag=1 then begin  //здесь Sender.Tag=1
    //применить
    if IdPPSelect.Value<1 then begin //здесь IdPPSelect.Value=0
      // новая ПП
        q:='select ifnull(max(id)+1,1) NextId from pp';
        RunSQL(q,nil,230);
    end else begin

    end;
  end;
  WinParamPP.CloseClient(ClientName);
end.
кусок процедуры "выполнился запрос"
Код: (delphi)
var i,row : integer;
    fl : boolean;
    s,s1 : string;
    cb : TM_ComboBox;
    txt : TM_Text;
    varVes,tmpVar : TM_Variable;
    d1,d2 : double;
begin
  case DataSet.Tag of
    230:begin //старт создания ПП
      if PPIdGP.Value>0 then
        PPNewId.Value:=DataSet.Fields[0].AsInt;
        s:='INSERT INTO '+DBName+'`pp` (`id`,`kod`,`Name`,`typ`,`time_suh`,`time_mokr`,`speedmel`,`plotn`,'+
            '`VesPart`, `VesPort`, `PortKol`, `PortCompl`, `Compl`, `idGP`, dtCreate) '+
        'VALUES ('+
          QuotedStr(PPNewId.AsStr)+', '+
          QuotedStr(PPKod.AsStr)+', '+
          QuotedStr(PPName.AsStr)+', '+
          QuotedStr(PPTyp.AsStr)+', '+
          QuotedStr(PPSuh.AsStr)+', '+
          QuotedStr(PPMokr.AsStr)+', '+
          QuotedStr(PPSpeedMel.AsStr)+', '+
          QuotedStr(PPPlotn.AsStr)+', '+
          QuotedStr(PPPart.AsStr)+', '+
          QuotedStr(PPPort.AsStr)+', '+
          QuotedStr(PPKolPort.AsStr)+', '+
          QuotedStr('0')+', '+
          QuotedStr('0')+', '+
          QuotedStr(PPIdGP.AsStr)+', '+
          MySQLDateTime(Now, dttSecond)+');';
        // добавили ПП
        //дальше детализация
        Text281.Text:=s;  //вот здесь s почему-то равно не 'INSERT INTO `dbname`.`pp` (`id`,....' , а ''''''''''''''''INSERT INTO `dbname`.`pp` (`id`,....'
        RunSQL(s,nil,231);
    end;
end;
откуда то в начале строки берутся куча кавычек.
если перед строкой присвоения (s:='INSERT INTO '+DBName+'`pp` (`id`,) поставить присвоение переменной s чего-нибудь, то все будет нормально.
т.е.
Код
s:='что-нибудь';
s:='INSERT INTO '+DBName+'`pp` (`id`,...
то всё будет нормально.

« Изменён: 22 Марта 2021, 20:16:57 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: В строке произвольно появляется мусор
« Ответ #1 : 22 Марта 2021, 20:29:20 »
Здравствуйте.

Проблема возможно возникает из-за смешивания кодировок, либо из-за неправильной работы с указателями в других скриптах. Строку "Text281.Text:=s;" нужно заменить на:
Код: (delphi)
Text281.Text := UTF8Encode(s);
Также непонятно какой тип имеет переменная DBName и как значение присваивается в неё. Какой тип данных у колонок в таблице "pp"? Таблица "pp" создана в кодировке UTF8?
Чтобы выявить другие возможные причины нужно проверять проект. Если есть желание, то вышлите проект на support@simple-scada.com для проверки.
« Изменён: 22 Марта 2021, 20:55:03 от Simple-Scada »

dima_k

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: В строке произвольно появляется мусор
« Ответ #2 : 23 Марта 2021, 09:15:09 »
Смысл кода

Код: (delphi)
Text281.Text:=s;

только в том, чтобы увидеть, что передается в RunSQL в следующей строке кода.
Код: (delphi)
RunSQL(s,nil,231);
А там возникает ошибка из за того, что перед запросом идет куча кавычек.
Переменная "s" имеет тип String в RunSQL первый параметр тоже String. Указатели нигде не использую.
« Изменён: 23 Марта 2021, 09:16:25 от dima_k »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: В строке произвольно появляется мусор
« Ответ #3 : 23 Марта 2021, 09:40:35 »
Цитировать
только в том, чтобы увидеть, что передается в RunSQL в следующей строке кода.
Это понятно из кода и сути не меняет. Если Вы хотите видеть на экране достоверное значение, нужно использовать UTF8Encode, иначе можно сомневаться в каждом символе который будет отображен в компоненте Text281.

Какой тип данных у колонок в таблице "pp"? Таблица "pp" создана в кодировке UTF8?

dima_k

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: В строке произвольно появляется мусор
« Ответ #4 : 23 Марта 2021, 11:09:58 »
Я повесил обработчик на событие "Ошибка SQL" - там сообщение об ошибке тоже с кучей кавычек.

В проекте много где происходит чтение, запись, удаление в БД. Везде для формирования запроса используется какая-то переменная типа String, которая потом передается в RunSQL. И только здесь непонятный косяк.
« Изменён: 23 Марта 2021, 11:13:02 от dima_k »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: В строке произвольно появляется мусор
« Ответ #5 : 23 Марта 2021, 11:59:07 »
Судя по имеющейся информации и т.к. приведённый Вами код всегда правильно работает на наших ПК, причина может связана с таблицей "pp", её структурой и данными  в ней. В теории в ней могут быть какие-то данные, которые скада копирует с ошибками связанными с памятью (например касаемо строковых данных). Если это предположение верно, то если переместить код из скрипта "выполнен SQL-запрос" в обычный скрипт (например по событию OnClick) - проблема исчезнет. Т.е. мы предполагаем что появление лишних кавычек возможно только в скрипте с типом "выполнен SQL-запрос", т.к. только в нём скада выполняет копирование данных из набора который вернула СУБД.
Мы попытались проверить это создав таблицу "pp" с теми же колонками, которые перечислены в Вашем запросе, чтобы максимально приблизить все действия к тем, которые выполняются у Вас. Но проблем не возникло, лишние символы не появились. Правда отличия всё равно есть, ведь типы колонок и данные в них пришлось заполнять наугад, т.к. от Вас дважды не удалось получить информацию о таблице "pp", видимо она является секретной.
К сожалению, по имеющейся информации ничего другого предположить не можем. А чтобы что-то изменить в любом случае сначала нужно повторить проблему.
« Изменён: 23 Марта 2021, 13:07:08 от Simple-Scada »

dima_k

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: В строке произвольно появляется мусор
« Ответ #6 : 23 Марта 2021, 16:11:09 »
CREATE TABLE `pp` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `kod` varchar(46) NOT NULL,
  `name` varchar(100) DEFAULT '',
  `typ` int DEFAULT '0',
  `time_suh` int DEFAULT '30',
  `time_mokr` int DEFAULT '150',
  `speedmel` float DEFAULT '10' COMMENT 'Плотность для рассчета скорости подачи мелассы',
  `plotn` int DEFAULT '1000' COMMENT 'Плотность готового продукта для расчета заполненности бункеров',
  `VesPart` int DEFAULT '1000',
  `VesPort` int DEFAULT '1000',
  `PortKol` int NOT NULL DEFAULT '0',
  `PortCompl` int DEFAULT '0' COMMENT 'Кол-во выполненных порций',
  `Compl` int DEFAULT '0' COMMENT ' 1 - закончилось приготовление \n 2 - закончилась выгрузка в силоса',
  `idGP` int NOT NULL DEFAULT '0',
  `State` int DEFAULT '0' COMMENT ' 1 - активирован \n 2 - запущен в производство',
  `inUseK` int DEFAULT '0',
  `inUseD` int DEFAULT '0',
  `inUseJ1` int DEFAULT '0',
  `inUseJ2` int DEFAULT '0',
  `inUseGran` int DEFAULT '0',
  `inUseNap` int DEFAULT '0',
  `inUseMel` int DEFAULT '0',
  `dtCreate` datetime DEFAULT '2001-01-20 00:00:00',
  `dtStart` datetime DEFAULT '2001-01-20 00:00:00',
  `dtEnd` datetime DEFAULT '2001-01-20 00:00:00',
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

dima_k

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: В строке произвольно появляется мусор
« Ответ #7 : 23 Марта 2021, 16:15:37 »
Судя по имеющейся информации и т.к. приведённый Вами код всегда правильно работает на наших ПК, причина может связана с таблицей "pp", её структурой и данными  в ней.

Не думаю. К моменту выполнения
RunSQL(s,nil,231);
Переменная s уже приходит с кучей начальных кавычек. А ведь переменная s формируется буквально в предыдущей строке скрипта.

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

s:='select * from pp';
RunSQL(s,nil,0);  <--- вот здесь s содержит не <select * from pp> а <''''''''''''select * from pp>, что, естественно воспринимается сервером MySql как ошибка.

Если я слегка изменю код:
s:='ля-ля-ля';
s:='select * from pp';
RunSQL(s,nil,0);  <--- вот здесь s содержит <select * from pp>
« Изменён: 23 Марта 2021, 16:21:10 от dima_k »

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 149
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Re: В строке произвольно появляется мусор
« Ответ #8 : 23 Марта 2021, 16:30:45 »
Во-первых поле id AUTO INCREMENT так зачем его вычислять и писать в базу? Если нужно получить в переменную id только что внесенной записи, то делаем запись в базу по нажатию кнопки и закрытию окна и сразу же шлём следующий запрос на получение max(id) и уже по этому запросу в SQLDone записываем в переменную последний id.
Во-вторых зачем вообще в скрипте промежуточная переменная "s"? Вроде она нигде больше не используется, может просто вписать запрос в процедуру RunSQL?
Код: (delphi)
RunSQL('INSERT INTO '+DBName+'`pp` (`id`,`kod`,`Name`,`typ`,`time_suh`,`time_mokr`,`speedmel`,`plotn`,'+
            '`VesPart`, `VesPort`, `PortKol`, `PortCompl`, `Compl`, `idGP`, dtCreate) '+
        'VALUES ('+
          QuotedStr(DataSet.Fields[0].AsStr)+', '+
          QuotedStr(PPKod.AsStr)+', '+
          QuotedStr(PPName.AsStr)+', '+
          QuotedStr(PPTyp.AsStr)+', '+
          QuotedStr(PPSuh.AsStr)+', '+
          QuotedStr(PPMokr.AsStr)+', '+
          QuotedStr(PPSpeedMel.AsStr)+', '+
          QuotedStr(PPPlotn.AsStr)+', '+
          QuotedStr(PPPart.AsStr)+', '+
          QuotedStr(PPPort.AsStr)+', '+
          QuotedStr(PPKolPort.AsStr)+', '+
          QuotedStr('0')+', '+
          QuotedStr('0')+', '+
          QuotedStr(PPIdGP.AsStr)+', '+
          MySQLDateTime(Now, dttSecond)+');', nil, 231);
 
« Изменён: 23 Марта 2021, 16:34:59 от Timothy Clement »

dima_k

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: В строке произвольно появляется мусор
« Ответ #9 : 23 Марта 2021, 16:49:32 »

Во-вторых зачем вообще в скрипте промежуточная переменная "s"? Вроде она нигде больше не используется, может просто вписать запрос в процедуру RunSQL?


я её завел, чтобы в text записать и увидеть, что же я шлю в RunSQL.
Потому-что в начале была ошибка при выполнении RunSQL.

P.S. Спасибо, что ткнули в auto increment поле.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: В строке произвольно появляется мусор
« Ответ #10 : 23 Марта 2021, 17:58:04 »
Цитировать
Переменная s уже приходит с кучей начальных кавычек.
Это верно, если проблема связана с результатом выборки из таблицы "pp" после запроса к которой был вызван скрипт "Выполнен SQL-запрос" в котором Вы получаете проблему. Если наше предположение верно, то переменная "s" с самого начала будет проблемной. Пожалуйста, проделайте простой тест описанный ниже, который даст необходимые данные.

Цитировать
Упрощаю код.
s:='select * from pp';
RunSQL(s,nil,0);
Вы проверяли именно этот код? В идеале нужно оставить такой код:
Код: (delphi)
var
  s: string;
begin
  s := 'select * from pp';
  RunSQL(s, nil, 0);
end.
Чтобы в коде не было никаких локальных переменных помимо s и ничего другого помимо двух строк между begin..end. Добавляются ли лишние символы? Если да, то уберите этот код со скрипта "Выполнен SQL-запрос" и вставьте его в скрипт OnClick кнопки. Запустите проект и кликните кнопку. Добавляются ли лишние символы в этом случае?
« Изменён: 23 Марта 2021, 18:02:17 от Simple-Scada »

dima_k

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: В строке произвольно появляется мусор
« Ответ #11 : 24 Марта 2021, 12:07:24 »
Долго я экспериментировал.
SQL запрос, чтобы отвязавться от базы заменил на "select 1". Ошибка исчезала только при капитальном облегчении скрипта "Выполнен SQL-запрос", что меня не устраивает, т.к. там всё нужно и полезное. И к тому времени я был уверен, что это косяк компиляции скрипта.

В этом скрипте в структуре
  case DataSet.Tag of

  end;

индексы у меня идут по порядку. Косяк проявляется в индексе 230. Нашел, что если не меняя кода, просто переместить проблемный 230 индекс выше 225 или ниже 232 - косяк исчезает.

Во вложении весь скрипт.

Если надо могу весь проект отослать на email
« Изменён: 24 Марта 2021, 12:18:29 от dima_k »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3000
    • Просмотр профиля
    • Simple-Scada
Re: В строке произвольно появляется мусор
« Ответ #12 : 24 Марта 2021, 14:24:04 »
dima_k, то что Вы пишете  - подтверждает наши изначальные предположения о связи полученного через SQL-запрос набора данных с лишними символами. Самый простой способ выявить точную причину проблемы это выслать нам текущую версию проекта и выборку всех данных из таблицы "pp". По этой ссылке можно прочесть как сделать выборку и сохранить её в файл. Только у Вас SQL-запрос должен быть таким: "SELECT * FROM `имя_базы`.`pp`". Другой путь - сделать копию БД и выслать её нам. Он проще и описан здесь.
Тогда у нас будет та же структура данных, что и у Вас. И с очень большой вероятностью нам, наконец, удастся повторить проблему. А если её удастся повторить, то (если она касается скады) мы выявим и исправим её очень быстро.
Со своими данными (создали таблицу "pp" с помощью Вашего SQL-запроса. Затем заполнили её случайными данными) мы уже проверяли неоднократно и проблема никогда не возникает. Поэтому думаем что выявить причину можно только как описано выше.

dima_k

  • Новичок
  • *
  • Сообщений: 28
    • Просмотр профиля
Re: В строке произвольно появляется мусор
« Ответ #13 : 24 Марта 2021, 15:16:36 »
Куда высылать?

Simple Scada

  • Глобальный модератор
  • *****
  • Сообщений: 166
    • Просмотр профиля
    • Simple-Scada
Re: В строке произвольно появляется мусор
« Ответ #14 : 24 Марта 2021, 15:28:54 »
Чтобы выявить другие возможные причины нужно проверять проект. Если есть желание, то вышлите проект на support@simple-scada.com для проверки.
« Изменён: 24 Марта 2021, 21:09:29 от Simple-Scada »