PDA

Просмотр полной версии : MYSQL + СПК110, вставка переменных в запрос к БД



bdw11@mt-holding.ru
14.03.2022, 23:17
Добрый день. Есть пример запроса, подскажите, как можно реализовать вставку переменных в запрос?:confused:
И как быть если требуется в БД записывать сразу много строк (10-20)?

'INSERT INTO new_table (name, time, value) values ("переменная1, "переменная2, "переменная3")'

Евгений Кислов
15.03.2022, 06:31
Добрый день. Есть пример запроса, подскажите, как можно реализовать вставку переменных в запрос?:confused:
И как быть если требуется в БД записывать сразу много строк (10-20)?

'INSERT INTO new_table (name, time, value) values ("переменная1, "переменная2, "переменная3")'

Добрый день.
Насколько я понимаю - пример работы с MySQL вы уже нашли, и теперь у вас только частные вопросы.


как можно реализовать вставку переменных в запрос?

Например, так (с использованием функции ReplaceSubstring из библиотеки OwenStringUtils):



PROGRAM PLC_PRG
VAR
sVar1: STRING := 'переменная1';
sVar2: STRING := 'переменная2';
sVar3: STRING := 'переменная3';

sSqlStatement: STRING(255);
END_VAR
VAR CONSTANT
c_sSqlStatementTemplate: STRING(255) := 'INSERT INTO new_table (name, time, value) values ("#VAR1#", "#VAR2#", "#VAR3#")';
END_VAR


// этот код лучше выполнять только в нужный момент по событию

sSqlStatement := OSU.ReplaceSubstring(c_sSqlStatementTemplate, '#VAR1#', sVar1);
sSqlStatement := OSU.ReplaceSubstring(sSqlStatement, '#VAR2#', sVar2);
sSqlStatement := OSU.ReplaceSubstring(sSqlStatement, '#VAR3#', sVar3);


59682


И как быть если требуется в БД записывать сразу много строк (10-20)?

Можно в операторе INSERT указать несколько наборов значений:
https://www.mysqltutorial.org/mysql-insert-multiple-rows/

В некоторых случаях будет эффективнее использовать оператор LOAD DATA INFILE (особенно если есть задача архивировать эти данные и в ПЛК):
http://www.mysql.ru/docs/man/LOAD_DATA.html

bdw11@mt-holding.ru
15.03.2022, 16:29
А как в sVar1-sVar3 передать именно значение переменной?, с остальным вроде бы разобрался. При таком объявлении 'переменная1' превращается просто в строку

sVar1: STRING := 'переменная1';
sVar2: STRING := 'переменная2';
sVar3: STRING := 'переменная3';

Евгений Кислов
15.03.2022, 16:50
А как в sVar1-sVar3 передать именно значение переменной?, с остальным вроде бы разобрался. При таком объявлении 'переменная1' превращается просто в строку

sVar1: STRING := 'переменная1';
sVar2: STRING := 'переменная2';
sVar3: STRING := 'переменная3';

Приведите пример данных, которые вы хотите записать в БД.
Они ведь уже существуют в вашей программе в виде переменных?
Тогда просто покажите их объявление.

bdw11@mt-holding.ru
15.03.2022, 17:52
Спасибо за помощь, разобрался вроде, поправьте если есть косяки.

В главной программе объявил 3 переменные с датчиков температуры "temp_in".
В ФБ для использования MySQL-клиента объявил 3 input переменные "sVar"
Помощью TO_STRING в главной программе преобразовал "temp_in1" в STRING и адресовал в переменную "sVar1" ФБ для использования MySQL-клиента.


PROGRAM PLC_PRG
VAR
temp_in1: REAL; //датчик температуры 1
temp_in2: REAL; //датчик температуры 2
temp_in3: REAL; //датчик температуры 3

END_VAR

59703


FUNCTION_BLOCK MySQL_CLIENT

VAR_INPUT
sVar1: STRING;
sVar2: STRING;
sVar3: STRING;
END_VAR


VAR CONSTANT
c_sSqlStatement: STRING(255) := 'INSERT INTO new_table (name, time, value) values ("#VAR1#", "#VAR2#", "#VAR3#")';
END_VAR



fbRiseEdge(CLK := xExecute);

IF fbRiseEdge.Q THEN
sSqlStatement := OSU.ReplaceSubstring(c_sSqlStatement, '#VAR1#', sVar1);
sSqlStatement := OSU.ReplaceSubstring(sSqlStatement, '#VAR2#', sVar2);
sSqlStatement := OSU.ReplaceSubstring(sSqlStatement, '#VAR3#', sVar3);
END_IF

Евгений Кислов
15.03.2022, 18:01
Приведенный вами код должен работать.

Чтобы добавить входы sVar1, sVar2, sVar3 к квадратику ФБ на холсте: ПКМ на ФБ - Контакты - Сброс контактов.

bdw11@mt-holding.ru
16.03.2022, 14:55
Спасибо за помощь

bdw11@mt-holding.ru
17.03.2022, 20:59
Столкнулся со следующей проблемой. STRING ограничен 255 символами, склеил нескольких строк в одну с помощью OSU.StrConcatA и поместил в sCommand: STRING(500), в результате получилась такой запрос:

mysql -s -utest -p11 -h 10.33.1.101 --database=test --default-character-set=cp1251 -e "INSERT INTO new_table (date, time, value) values (CURRENT_DATE(), CURRENT_TIME(), 24.42029), (CURRENT_DATE(), CURRENT_TIME(), 19.95781), (CURRENT_DATE(), CURRENT_TIME(), 22.24042)"
который MYSQL отказывается почему то принимать. В БД ничего не приходит.

Может быть есть способ сформировать адекватный запрос в БД?
Задача состоит в том, чтобы раз в 1 сек зафиксировать показания датчиков ~20шт (sVar1-sVarn), приклеить метку времени и передать это все в БД.
На данный момент имею вот такой код:

FUNCTION_BLOCK MySQL_CLIENT

VAR_INPUT
xExecute: BOOL;
sUser: STRING(30);
sPassword: STRING(30);
sIpAddr: STRING(30);
sDatabase: STRING(30);
sVar1: STRING(30);
sVar2: STRING(30);
sVar3: STRING(30);
END_VAR

VAR_OUTPUT
xDone: BOOL;
xBusy: BOOL;
xError: BOOL;
asResult: ARRAY [1..255] OF STRING(255);
usiCountOfStrings: USINT;
xOverFlow: BOOL;
END_VAR

VAR
sCommand: STRING(500);
fbSe4: CmpSysExec.SysExecute4;
fbRiseEdge: R_TRIG;
END_VAR

VAR CONSTANT
c_sCommand: STRING(255):= 'mysql -s -u#USER# -p#PASS# -h #HOST# --database=#DATABASE# --default-character-set=cp1251 -e ';
END_VAR


fbRiseEdge(CLK := xExecute);

IF fbRiseEdge.Q THEN
sCommand := OSU.ReplaceSubstring(c_sCommand, '#USER#', sUser);
sCommand := OSU.ReplaceSubstring(sCommand, '#PASS#', sPassword);
sCommand := OSU.ReplaceSubstring(sCommand, '#HOST#', sIpAddr);
sCommand := OSU.ReplaceSubstring(sCommand, '#DATABASE#', sDatabase);

OSU.StrConcatA(ADR('"INSERT INTO new_table (date, time, value) values (CURRENT_DATE(), CURRENT_TIME(), '), ADR(sCommand), SIZEOF(sCommand));
OSU.StrConcatA(ADR(sVar1), ADR(sCommand), SIZEOF(sCommand));
OSU.StrConcatA(ADR('), '), ADR(sCommand), SIZEOF(sCommand));
OSU.StrConcatA(ADR('(CURRENT_DATE(), CURRENT_TIME(), '), ADR(sCommand), SIZEOF(sCommand));
OSU.StrConcatA(ADR(sVar2), ADR(sCommand), SIZEOF(sCommand));
OSU.StrConcatA(ADR('), '), ADR(sCommand), SIZEOF(sCommand));
OSU.StrConcatA(ADR('(CURRENT_DATE(), CURRENT_TIME(), '), ADR(sCommand), SIZEOF(sCommand));
OSU.StrConcatA(ADR(sVar3), ADR(sCommand), SIZEOF(sCommand));
OSU.StrConcatA(ADR(')"'), ADR(sCommand), SIZEOF(sCommand));
END_IF

fbSe4
(
xExecute := fbRiseEdge.Q,
sCommand := sCommand,
sOutput => asResult,
cntReadStr => usiCountOfStrings,
xOverFlow => xOverFlow,
xDone => xDone,
xBusy => xBusy,
xError => xError
);

Евгений Кислов
18.03.2022, 06:18
https://owen.ru/forum/showthread.php?t=28167&p=361101&viewfull=1#post361101

В вашем случае:
https://linux.die.net/man/1/mysql



You can execute SQL statements in a script file (batch file) like this:

mysql db_name < script.sql > output.tab