Показано с 1 по 4 из 4

Тема: ПЛК200. Работа с SQLite. SysExecute4 и SysExecute5. Не могу выполнить длинную команду

  1. #1

    По умолчанию ПЛК200. Работа с SQLite. SysExecute4 и SysExecute5. Не могу выполнить длинную команду

    Всем здоровья!

    Работаю с БД SQLite. Пока отправлял короткие запросы, то CmpSysExec.SysExecute4 для этого подходит хорошо. Но запрос с условиями и объединением таблиц получается больше чем 255 символов и на вход CmpSysExec.SysExecute4 такую команду я уже не могу подать.

    Попробовал использовать CmpSysExec.SysExecute5. ФБ завершает свое выполнение без ошибок, но в ответе всегда пустая строка. Даже на короткий запрос.

    Попробовал использовать CmpSysExec.SysExecute4 разбивая команду на 2 строки. После первой строки в ответе пустая строка. Я так понял, что приглашение ввода ">" я не могу увидеть через CmpSysExec.SysExecute4, потому что это приглашение ввода от sqlite3 а не от linux. Но ладно, я знаю, что отправил не всю команду, в ответ ничего не получил - значит ошибки нет. Тогда отправляю вторую часть команды, а в ответе все равно пусто.

    Может быть есть у кого пример работы с SQL через CmpSysExec.SysExecute5?

    Код который дает пустые строки не могу выложить я его со злости удалил. Остался только рабочий код с короткими запросами через CmpSysExec.SysExecute4.

  2. #2
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,254

    По умолчанию

    Вы же когда сформировали команду в плк, можете её скопировать и запустить в консоли чтоб посмотреть работает ли она как надо
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

  3. #3

    По умолчанию

    Я знаю. Команда рабочая. Я брал короткую команду, которая выполнялась с SysExecute4, и передавал указатель на нее в SysExecute5. Формирование самой команды не менял.

    А когда разбивал на две строки, то да, стоило бы проверить, но забыл о таком способе.

  4. #4

    По умолчанию

    В общем, добрался до документации на сайте ОВЕН. Оказывается SysExecute5 каждую новую строку из терминала пишет по заново по переданному ей указателю, перетирая предыдущие строки и последняя строка обязательно пустая. То есть необходимо вручную во время выполнения ФБ подкидывать ему новый указатель.

    Вот такой код у меня заработал

    Код:
    FUNCTION_BLOCK SQLQuery IMPLEMENTS itfSQLQuery
    VAR_INPUT
    	xExecute:					BOOL;
    END_VAR
    VAR_OUTPUT
    	xDone:						BOOL;
    	xBusy:						BOOL;
    	xError:						BOOL;
    	usiCurQuery : USINT := 0; //текущий запрос 0 - запрос обработан; 1 - количество строк; 2- данные
    END_VAR
    VAR
    	sPathToDb:					STRING	:=  '/home/ftp/kormplus_plc.db'; //путь к базе данных
    	sCommand:		STRING(2047); //переменная для целой команды
    	sSQLQuery:		STRING(2000); //переменная для запроса
    	sTable : STRING; //Имя таблицы
    	sColumn : STRING; //Имя столбца
    	sWhereStatement : STRING(2000); //условия запроса
    	iItemsCount : INT; //количество доступных строк в таблице
    	fbSe5 :		 	CmpSysExec.SysExecute5;
    	fbRiseEdge :		R_TRIG;
    	// Результат выполнения запроса
    	asResult :	ARRAY[1..255] OF STRING(255);
    	
    	x : UINT;
    	i : USINT := 0;
    	// количество строк в ответе
    	usiCountOfStrings:			USINT;
    	// TRUE - при выдаче ответа произошло переполнение массива, часть информации потеряна
    	xOverFlow:					BOOL;
    END_VAR
    VAR CONSTANT
    	// шаблон запроса, можно отредактировать под себя
    	// см. https://linux.die.net/man/1/sqlite3
    	c_sCommand:		STRING(255) := 'sqlite3 #PATH_TO_FILE# "#SQL#"';
    	c_sCountSelect : STRING(255) := 'SELECT COUNT(#COLUMN#) FROM #TABLE# #WHERE#;';
    	c_sSelect : STRING(255) := 'SELECT #COLUMN# FROM #TABLE# #WHERE#;';
    END_VAR
    
    fbRiseEdge(CLK := xExecute);
    
    IF fbRiseEdge.Q THEN
    	i := 1;
    	xOverFlow := FALSE;
    	usiCountOfStrings := 0;
    END_IF
    
    fbSe5
    (
    	xExecute 	:= xExecute,
    	pCommand := ADR(sCommand),
    	szCommand := TO_DWORD(STU.StrLenA(ADR(sCommand))),
    	pOutput := ADR(asResult[i]),
    	szOutput := SIZEOF(asResult[i]),
    	uiOutputSize => x,
    	xDone       => xDone,
    	xBusy       => xBusy,
    	xError      => xError
    );
    
    IF fbSe5.xBusy AND asResult[i] <> '' AND i < 255 THEN
    	i := i + 1;
    	IF i = 255 OR x > 255 THEN
    		xOverFlow := TRUE;
    	END_IF 
    END_IF
    
    IF fbSe5.xDone THEN
    	usiCountOfStrings := i -1;
    END_IF

Похожие темы

  1. Не могу подключиться к ПЛК200
    от ivydy в разделе ПЛК2хх
    Ответов: 22
    Последнее сообщение: 01.02.2024, 13:12
  2. Ответов: 10
    Последнее сообщение: 18.07.2023, 19:51
  3. Multi-Protocol MasterOPC Server запись тега в SQLite
    от Bigpapasugrob в разделе OPC Серверы
    Ответов: 0
    Последнее сообщение: 21.09.2022, 11:48
  4. Выполнить запрос HTTP_GET
    от Андрей Шатохин в разделе Сетевые технологии
    Ответов: 3
    Последнее сообщение: 02.11.2016, 10:10

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •