Стартовая страница › Форумы › Разработка и интеграция › Экспорт большого количества каналов в SQL
- В этой теме 1 ответ, 2 участника, последнее обновление 9 лет назад сделано
Mikhail.
-
АвторЗаписи
-
29.08.2017 в 09:30 #7146
Kazam
УчастникВсем привет.
При увеличении количества входных каналов, прямое подключение к серверу Rapid Scada для получения значений, перестает быть эффективным.
Итого дано: около 4000 входных каналов. 600 каналов управления.
Задача: положить значения и свойства каналов в SQL.Что придумал:
В методе OnServerStart: получаем таблицы КП, Unit, ParamTable
В методе OnCurDataCalculated: получаем текущий срез и пишем его в DataTable, который в свою очередь, через расширение:
public static class DataTableExtensions { public static void WriteToCsvFile(this dataTable, string filePath) { StringBuilder fileContent = new StringBuilder(); foreach (var col in dataTable.Columns) { fileContent.Append(col.ToString() + ";"); } fileContent.Replace(";", System.Environment.NewLine, fileContent.Length - 1, 1); foreach (DataRow dr in dataTable.Rows) { foreach (var column in dr.ItemArray) { if (column.GetType() == typeof(DateTime)) { fileContent.Append("" + String.Format("{0:yyyy-MM-dd HH:mm:ss.000}", column) + ";"); } else { if (String.IsNullOrEmpty(column.ToString())) { fileContent.Append(" ;"); } else { fileContent.Append("" + string.Format("{0:F12}", column).Replace(',', '.') + ";"); } } } fileContent.Replace(";", System.Environment.NewLine, fileContent.Length - 1, 1); } System.IO.File.WriteAllText(filePath, fileContent.ToString()); } }Пишем в CSV файл.
Ну а далее с CSV файлом делаем, что хотим.
Например пишем в PostgreSQL.
вот что получилось:public override void OnCurDataCalculated(int[] cnlNums, SrezTableLight.Srez curSrez) { // the method executes after current data calculation (approximately every 100 ms) // метод выполняется после вычисления дорасчётных каналов текущего среза (примерно каждые 100 мс) dt.Rows.Clear(); int cnlCnt = curSrez.CnlNums.Length; for (int i = 0; i < cnlCnt; i++) { DataRow dr = dt.NewRow(); dr["cnlnum"] = Convert.ToInt32(curSrez.CnlNums[i]); dr["value"] = curSrez.CnlData[i].Val; dr["datetime"] = DateTime.Now; dt.Rows.Add(dr); } dt.WriteToCsvFile(day_filename); using (NpgsqlConnection conn_table = new NpgsqlConnection(conn_param)) { conn_table.Open(); NpgsqlCommand comm = new NpgsqlCommand(sql, conn_table); var result = comm.ExecuteNonQuery(); conn_table.Dispose(); } }Отдельно о SQL запросе: string sql = @»CREATE TEMP TABLE incnls_temp (cnlnum DOUBLE PRECISION, datetime TIMESTAMP, value DOUBLE PRECISION);
copy incnls_temp (cnlnum, datetime, value) FROM ‘c:\\scada\\current\\current.csv’ DELIMITER ‘;’ CSV HEADER;
UPDATE incnls SET value = incnls_temp.value, datetime = incnls_temp.datetime FROM incnls_temp WHERE incnls.cnlnum = incnls_temp.cnlnum;
DROP TABLE incnls_temp
«;
Создаем копию таблицы входных каналов в SQL, пишем в нее данные, далее делаем Update в основной таблице и дропаем временную.Что это дает: при пакетной обработке каналов получаем существенное увеличение производительности, в отличие от классического подхода InsertCommand.
29.08.2017 в 17:15 #7151
MikhailМодераторСпасибо. Если замените DataTable на другие структуры, будет ещё быстрее, т.к. DataTable — сложный и медленный класс.
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.