Всё получилось, всё работает с запросами любой длины
Объявления
Код:
(*-------------------------------------------------------------------------------------------------------------------
Перед использованием нужно добавить в файл /etc/freetds.conf секции:
//(в рамках примера в сервере collation = Cyrillic_General_CI_AS)
//
//[read]
// host = <IP-адрес сервера> (например, host = 10.2.7.70)
// port = 1433
// tds version = 7.3
// client charset = WINDOWS-1251 (кодировка выбирается в зависимости от конкретной задачи)
//
//[write]
// host = <IP-адрес сервера>
// port = 1433
// tds version = 7.3
// client charset = UTF-8
//
//где:
//host - IP-адрес сервера БД (например, host = 10.2.7.70)
//client charset - используемая кодировка (выбирается в зависимости от настроек и содержимого БД)
-------------------------------------------------------------------------------------------------------------------*)
FUNCTION_BLOCK My_MsSQL_CLIENT_Write (*ФБ для использования MsSQL-клиента. Запись*)
//Входы-Выходы
VAR_IN_OUT
xExecute: BOOL; //Запуск
END_VAR
//Входы
VAR_INPUT
sSqlStatement : WSTRING(65535); //Текст SQL-запроса
sBD_Name : WSTRING(255); //Имя БД
END_VAR
//Выходы
VAR_OUTPUT
//Стандартные выходы
xDone : BOOL; //Признак конца работы
xBusy : BOOL; //Признак занятости
xError : BOOL; //Признак ошибки
END_VAR
//Внутренние параметры
VAR
//R-триггер для фиксации запуска работы ФБ
fbRiseEdge: R_TRIG;
//Команда отправки на контроллерную консоль
sCommand_Real: STRING(255);
//Текст SQL-запроса в UTF8
sSqlStatement_UTF8: STRING(65535);
//Имя БД в UTF8
sBD_Name_UTF8: STRING(255);
//ФБ для отправки команд на контроллерную консоль
fbSe4: CmpSysExec.SysExecute4;
//Немножко магии для работы с файлом
pResult : POINTER TO SysFile.SysTypes.RTS_IEC_RESULT;
hFile : POINTER TO SysFile.SysTypes.RTS_IEC_HANDLE;
END_VAR
//Константы
VAR CONSTANT
//Команда отправки на контроллерную консоль
sCommand: STRING(255) := 'bsqldb -S write -U sa -P Password -D #BD_NAME# -i /home/SQL.txt';
END_VAR
Код
Код:
//Проверяем признак запуска
fbRiseEdge(CLK := xExecute);
xExecute := FALSE;
//Если появился признак запуска...
IF fbRiseEdge.Q THEN
//Имя БД в правильной кодировке UTF8
STU.ConvertUTF16toUTF8(ADR(sBD_Name), ADR(sBD_Name_UTF8), SIZEOF(sBD_Name_UTF8), FALSE);
sCommand_Real := OSU.ReplaceSubstring(sCommand, '#BD_NAME#', sBD_Name_UTF8);
//Текст SQL-запроса в правильной кодировке UTF8
STU.ConvertUTF16toUTF8(ADR(sSqlStatement), ADR(sSqlStatement_UTF8), SIZEOF(sSqlStatement_UTF8), FALSE);
//Пишем файл перед отправкой самого SQL-запроса
hFile := SysFile.SysFileOpen('/home/SQL.txt', SysFile.ACCESS_MODE.AM_WRITE, pResult);
SysFile.SysFileWrite(hFile, ADR(sSqlStatement_UTF8), TO_UDINT(StrLenA(ADR(sSqlStatement_UTF8))), pResult); //Пишем
SysFile.SysFileClose(hFile);
END_IF
//Блок отправки команды через контроллерную консоль
fbSe4
(
xExecute := fbRiseEdge.Q, //Запуск на исполнение по переднему фронту
sCommand := sCommand_Real, //Команда Linux - например 'ls /'
xAbort := FALSE, //Аварийный останов процесса
sOutput => , //Массив строк для сохранения вывода процесса
cntReadStr => , //Количество считанных строк вывода процесса
xOverFlow => , //Признак переполнения массива sOutput
xDone => xDone, //Признак завершённости процесса и/или того, что в данный момент не выполняется процесс Linux
xAborted => , //Признак прерывания по пользовательской команде
xError => xError, //Признак невозможности запуска из-за возникновекния ошибки
xBusy => xBusy, //Процесс выполняется
eErrorCode => //Код ошибки
);