Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108

Обновить заполненный DataTable из запроса select SQL

23.09.2022, 17:59. Показов 792. Ответов 2

Студворк — интернет-сервис помощи студентам
Собственно суть в заголовке, здесь лишь разжую немного.
Есть условная таблица на 100-400 тыс. записей находящаяся в бд (Firebird 2.5) на сервере в селе Хацапетовка связь с которым проходит через одно место и хорошо, если достигает 1Мб, НО стабильная что невозможно, содержащая по сути данные мониторинга. За которым нужно периодически хотя-бы следить и поглядывать. По самому оптимальному запросу получается около 60к. строк выборки при любом обновлении таблицы, т.е. там около 20 Мб летит по сети и ждёшь ты их под минут 5 точно.
Таблице был пришпандорен триггер на поле lastUpdate, который при insert/update лепит туда текущее время.
Ну и затея оптимизации состоит в том, чтоб в посылаемый select для поля lastUpdate выставлять условие последнего обновления таблицы на клиенте за 120 км.
Ну и на клиенте я получаю соответственно обрезок данных, которые мне нужно соединить и обновить с уже имеющимися данными у меня на форме.
По коду на форме имеем, что-то вроде такого:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.IO;
using System.Data;
using System.Text;
using FirebirdSql.Data.FirebirdClient;
using System.Linq;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text.RegularExpressions;
 
namespace MyProgramm
{
public partial class monitoring_update
{
        private FbTransactionOptions fbto;
        private FbTransaction fbt;
        private DateTime LastUpdateVW_dt { get; set; } = DateTime.MinValue;
        private DataTable DT_vwr { get; set; } = new DataTable();
 
public monitoring_update()
        {
            InitializeComponent();
            fbto = new FbTransactionOptions();
            fbto.TransactionBehavior = FbTransactionBehavior.Wait | FbTransactionBehavior.ReadCommitted | FbTransactionBehavior.RecVersion;
        }
 
//тратата код формы с вызовом на кнопке всякого в т.ч. load_dt
//в sql_text при этом передаётся самый обычный "select * from table_monitoring where lastUpdate >= " + LastUpdateVW_dt.ToShortDateString()
 
        public void load_dt(string sql_text, string connect, bool fl_show_message = true)
        {
            using (FbConnection fbcon = new FbConnection(connect))
            {
                fbt = null;
                try
                {
                    fbcon.Open();
                    fbt = fbcon.BeginTransaction(fbto);
                    using (FbCommand fbcom = new FbCommand(sql_text, fbcon, fbt))
                    {
                        DT_vwr.Load(fbcom.ExecuteReader()); //и вот на этом моменте я прям чёт затупил
                        LastUpdateVW_dt = DateTime.Now;
                    }
 
                    fbt.Commit();
                }
                catch (Exception ex1)
                {
                    try
                    {
                        if (fbt != null) fbt.Rollback();
                        if (fl_show_message)
                        {
                            log.add("Ошибка запроса данных. " + ex1.Message);
                        }
                    }
                    catch (Exception ex2)
                    {
                        if (fl_show_message)
                        {
                            log.add("Ошибка отката транзакции. " + ex2.Message");
                        }
                    }
                    return;
                }
            }
            return;
        }
 
//ну и после вызова load_dt DT_vwr подтягивается в соответствующую таблицу на форме, если не было ошибок в логе
 
}
}

DT_vwr.Load(fbcom.ExecuteReader()); //и вот на этом моменте я прям чёт затупил(
Пробовал и со всевозможными параметрами LoadOption.OverwriteChanges и т.д., нет не то.
Пробовал и через FbDataAdapter:
C#
1
2
3
4
5
6
7
8
9
10
11
using (FbCommand fbcom = new FbCommand(sql_text, fbcon, fbt))
                    {
                        using (FbDataAdapter fbdt_ = new FbDataAdapter(fbcom))
                        {
                            fbdt_.Fill(DT_vwr); //который ясно и чётко пишет:
//     Добавляет или обновляет строки в указанном диапазоне в объект System.Data.DataSet
        //     для получения соответствия строкам в источнике данных с использованием имени
        //     System.Data.DataTable.
//но нифига так не работает( В чём прикол?
                        }
                    }
Неа( всё не то.
Первая загрузка норм. А потом уже когда данные имеются и их только обновить, то всё( вылетает только так:
System.Reflection.TargetInvocationExcept ion: "Адресат вызова создал исключение"
...и здоровенный такой стек вызова.
Понимаю, что это как-то проще должно делаться, но я чёт догнать никак не могу, затупил( Ключевые поля всякие пробовал устанавливать (а уникальные значения там есть) - не помогло(
Гуглёж тоже не помогает, все тупо юзают новую таблицу и обновляет целиком ресы - а мне НЕ это надо! Мне существующую обновить надо.
Можно конечно попробовать ручками foreach все дела, но тоже та ещё трында такое количество записей перебирать, хочется как-то более встроенными средствами обойтись, которые уже и без меня оптимизировали... а то я с этой оптимизацией уже повешусь скоро(

Добавлено через 1 час 31 минуту
ааааа это капец
Нашёл решение вообще не там.
Короче делает буферную таблицу грузите в неё данные.
C#
1
DataTable buff_dt = new DataTable();
Указываете ключевое поле
C#
1
buff_dt.PrimaryKey = new DataColumn[] { buff_dt.Column[1] }; //ну или какое у вас там поле уникальное?
И потом праведный merge)
C#
1
DT_vwr.Merge(buff_dt, true);
Фсё я на сегодня фсё, я заколупался колупать FbDataAdapter

Добавлено через 5 минут
а ну и в DT_vwr соответственно тоже ключевое указываете + отслеживаете первую загрузку и т.д. и т.п.
...как тут свой ответ пометить?) @moderator ?)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.09.2022, 17:59
Ответы с готовыми решениями:

Как перебирать данные в DataTable по аналогии с SQL запросом SELECT?
Все доброго времени суток. Есть .csv таблица с полями : id, fio1, login1, fio2, login2, fio3, login3 и еще несколько полей с другой...

Использовать значения запроса SELECT в t-sql
Добрый день. Проблема такая. Мне нужно получить данные select'm а потом их далее использовать в триггере. С БД пока на Вы, а триггеры...

Результаты sql запроса select в QList
Всем привет! Нужно результаты запроса select записать в qlist. QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); ...

2
Эксперт .NET
 Аватар для Usaga
14147 / 9375 / 1351
Регистрация: 21.01.2016
Сообщений: 35,319
24.09.2022, 04:57
КиберСталкер21, хоть вы вроде бы и нашли решение, но я всё равно хочу заметить, что DataTable и DataAdapter'ы - это пример из начала двухтысячных. Это морально устаревший механизм работы с СУБД и про него лучше забыть. Вам достаточно было создать класс описывающий выборку из базы и сформировать на его основе коллекцию. И ненадо никаких merge и Primary Key.
0
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
24.09.2022, 09:10  [ТС]
Usaga, не переживайте, знаю, понимаю)
Просто я сейчас там разгребаю тонну костылей, в которых ещё и есть такие вещи, которые нужно оптимизировать до нельзя. А конкретно в этом ещё и участвует DevExpress на форме со своим ControlGrid в паре с gridView (в котором уже настроена кучка столбцов и перенастраивать которые бы не хотелось, т.к. там и checkbox'ы, и combobox'ы, и радужно-цветовое выделение и popupmenu, поиск и вообще чего только нет, короче там знатно прикололись), а к ним ещё и забиндена куча кнопок на форме тоже со своим "умопомрачительным" и спецефичным кодом и ломать их логику - это значит ломать пользователю мозг, а они этого не любят)
Со временем то конечно всё будет переделано как надо, но на это уйдёт куча времени, а пользователям нужно оптимизировать было "ещё вчера", поэтому пока так.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.09.2022, 09:10
Помогаю со студенческими работами здесь

Оператор Select SQL запроса, содержащий переменную
Здравствуйте. Помогите выполнить выборку Select. Запрос типа "select * from Table where Name = 'Иван'" выполняется без проблем. ...

Вывод результата запроса select sql в textbox
Всем здравствуйте! Понадобилось вывести в текстбокс результат запроса соединение через sqldatasourse declare @data varchar(max), ...

Реализация select запроса используя хранимую процедуру - sql server
Здравствуйте в программе на с# имеется запрос такого типа: private void button1_Click(object sender, EventArgs e) { ...

Как вывести результат запроса select в txt-файл? (Transact-SQL)
Как вывести результат запроса select в txt-файл? (Transact-SQL)

Обновить данные с DataTable в БД
Доброго времени суток! :) Есть БД ( просто для теста ), в ней таблица "table1" с 2 колонками: ID, Data. и заполненная некоторыми...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru