С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++ Builder: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
4 / 4 / 1
Регистрация: 03.12.2012
Сообщений: 55

Обойтись без использование глобальных переменных

20.02.2013, 19:00. Показов 1721. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Столкнулся на этапе написания программы с тем что необходимо анализировать данные за разный промежуток времени. Т.е. я опрашиваю периодически БД на изменение. В запросе мне приходят данные, анализируя с предыдущими делаю вывод были ли изменения в БД. Но мне нужно хранить где то эти данные?

Добавлено через 10 минут
Т.е. нужно хранить данные предыдущего опроса. Где их хранить?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.02.2013, 19:00
Ответы с готовыми решениями:

Без глобальных переменных.
1. void __fastcall TForm2::FormClick(TObject *Sender) { TPoint pt; GetCursorPos(&pt); int x = pt.x; int y = pt.y; ...

Получить значение переменной из потока без создания глобальных переменных
void __fastcall Pars::Execute() { Synchronize(&UpdateCaption); } ...

Использование глобальных переменных
Доброго времени суток всем! Есть такая задача. Задать значение переменной. затем инклудить скрипт и уже внутри него обработать эту...

17
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
20.02.2013, 19:02
Оформте данные в структуру, а с объект структуры объявите как член класс формы..
1
4 / 4 / 1
Регистрация: 03.12.2012
Сообщений: 55
20.02.2013, 20:25  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Оформте данные в структуру, а с объект структуры объявите как член класс формы..
Не совсем понял что имеете ввиду.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
20.02.2013, 22:09
Цитата Сообщение от doncelab Посмотреть сообщение
Не совсем понял что имеете ввиду.
Что тут непонятого я сказал ?
Слово структура незнакома и член класса ?
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
21.02.2013, 00:49
doncelab, уточните Вашу БД.
По идее можно использовать триггеры. А данные частично (или в нужной форме) зеркалировать в ту же БД.
0
6 / 6 / 1
Регистрация: 01.06.2012
Сообщений: 107
21.02.2013, 08:26
Цитата Сообщение от doncelab Посмотреть сообщение
Добавлено через 10 минут
Т.е. нужно хранить данные предыдущего опроса. Где их хранить?
В базе данных храни в той же самой, и запрос, должен обрабатывать сразу две операции, если есть изменения то к себе , нету стоять !
Стой на пути более тонкого клиента.
0
4 / 4 / 1
Регистрация: 03.12.2012
Сообщений: 55
21.02.2013, 08:36  [ТС]
База у меня firebird 2.5, многопользовательская. Есть служебная таблица в ней 3 поля UPDATES INSERTS DELETES, есть триггеры которые автоматически увеличивают счетчики для каждой из изменяемых таблиц. Т.е. подключаются несколько клиентов и начинаю работать, те изменения которые я вношу и меняются у меня в клиенте, а отслеживаю я изменения других участников, и корректно подгружаю изменения.
0
6 / 6 / 1
Регистрация: 01.06.2012
Сообщений: 107
21.02.2013, 11:33
Вапще всё круто, делаешь процедуру или функцию, что там в есть, чтобы могло сразу вернуть выборку, Просто вызываешь одну процедуру, а она автоматом проверяет, время когда ты делал последний раз обновление и есть ли изменения(у каждой записи, и у каждого изменения, должно быть такое понятие как dateimecreate и datetimeupdate или делать струтуру где нету не проводятся update а только добавление новых записей)...У меня автообновление везде так работает...Тоесть храню только одну переменную дату, кидаю в процедуру дату, а она возвращает данные, если нету новых данных не возвращаю. У меня к примеру нету смысла если небыло изменений перерисовывать дерево.

Но да конечно, если желание твоё сравнивать данные с таблицей, можешь создать вектор структур и делать сравнение. Но блин не красиво это.

Но у тебя клиент серверная технология, используй её на 100%

Есть ещё технология, в виде сервиса к СУБД, она может опавещать по tcp или http протоколу, находясь в процедуре или в тригере.
0
4 / 4 / 1
Регистрация: 03.12.2012
Сообщений: 55
21.02.2013, 15:31  [ТС]
У меня в базе к каждой таблице есть триггеры для каждого действия, которые увеличивают счетчик. Который я хочу анализировать и делать выводы об изменениях. dateimecreate и datetimeupdate я так понял что должны быть моими полями? Или есть служебные? Опишите поподробнее как реализовано у вас. Для меня такие технологии еще сложны, только разобрался с генераторами и триггерами. Я всегда думал что БД только для хранения данных, а они еще и оперируют этими данными.

Добавлено через 2 часа 35 минут
Нашел компонент IBEvents который будет регистрировать события посылаемые БД при изменении

Добавлено через 26 минут
В триггерах на нужные действия ставим post_event 'UPDATE_TABLE';, а в компоненте прописываем действия на событие
0
6 / 6 / 1
Регистрация: 01.06.2012
Сообщений: 107
22.02.2013, 07:57
Я так понимаю, что сейчас процесс только изучения клиент серверной технологии
Поэтому при работе с данными базами твоё приложение должно отвечать только за работу интерфейса. А всё остальное СУБД, только главное не давать на СУБД нагрузку, которая ему противопоказана(есть много литературы).

Короче там чисто новые механизмы о них либо препод расказывает, либо долго мануалы, либо просто от одного к другому. Поэтому надо будет пиши в аську 405349195
Но в любом случае не с тригеров начинай! Забудь про все свои запросы писанные на SQL теперь только вызовы процедур и функций с параметрами из СУБД. В твоём клиенте не должно быть не одного SQL запроса.
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
22.02.2013, 09:49
А самое верное будет прикрутить к началу каждой таблицы дополнительное поле, куда складывать значение даты/времени последнего внесения изменений, как предлагает doncelab, а в самой программе, как предлагает Avazart, хранить только не копию всех полей, а булевскую структуру с флагами только тех полей, которые данный конкретный клиент изменяет. По какому-нибудь событию (таймеру) каждый клиент будет проверять первое поле таблицы на предмет наличия изменений времени последнего редактирования таблицы, и если изменения есть, обновлять свою копию времени изменения и, самое главное, считывать только те поля, которые имеются в его структуре. Те, от изменения которых зависти логика его работы, а на остальные будет забивать.
Имя Фамилия АдресКомментарий
NULLNULLNULL31.12.2009 12:34
ВасяПупкинулица 1блондин
КоляПитерскийулица 2казел
...   

C++
1
2
3
4
5
6
7
8
struct Client1EditOnlyNameAndRestOnlyRead
{
String Name; // Сюда считывать из таблицы то, с чем хотим работать
} C1EONAROR[10];
 
TDateTime LastCangeAllTable;
bool NameHasChanged; // Вот эот вот можно объединить в структуру
                     //  (ну или во что-нибудь)(с фамилиями и прочим, если нужно)
C++
1
2
3
4
5
6
7
//...
C1EONAROR[0].Name = SELECT_FirstName;  // Заполнение структуры
C1EONAROR[1].Name = SELECT_SecName[1];
C1EONAROR[2].Name = SELECT_SecName[2];
 
LastChangeAllTable = SELECT_TimeOfFirstRowValue; // Получение времени из первой строки
NameHasChanged = false; // Сброс флага
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Timer()
{
if(LastChangeAllTable < SELECT_TimeOfFirstRowValue)
  {
  ShowMessage("Кто-то изменил таблицу");
  LastChangeAllTable = SELECT_TimeOfFirstRowValue;
  }
if(NameHasChanged)
  {
  UPDATE_C1EONARORForTable;
  UPDATE_TimeOfFirstRowValue;
  NameHasChanged = false;
  }
}

Можно пойти дальше и прикрутить в таблице к каждому столбцу по флагу. И, по изменению времени таблицы, считывать флаг интересующего нас столбца, и, к примеру, если нам нужно из таблицы только имя, а с остальным мы в данный момент не работаем, то будет всего два обращения к точно известным строкам таблицы, что сильно увеличит скорость работы.
Самое же лучшее это создать дополнительную таблицу, содержащую информацию о изменениях этой таблицы и вообще только к ней и обращаться.
Имя таблицыВремя последнего измененияФлаг изменения первого поляфлаг второго...
PersonalInfom12.12.12 12:44truefalsefalse
ShouldGoToHell11.03.99 15:55falsetruetrue
...    
Хотя вполне возможно все это велосипед и решается средствами субд.
1
 Аватар для Oxotnuk
78 / 78 / 6
Регистрация: 18.06.2009
Сообщений: 533
22.02.2013, 13:49
Без знаний СУБД будет тяжко но можно
Если оракл то есть псевдоколонка "номер последней транзакции которая его изменила". по умолчанию ведется на весь блок, но можно персонально для отдельной таблицы включть индивидуально на строку.
в Mssql/sybase есть timestamp , когда в строку внесено изменение
а перенос данных - отоборать данные по данной колонке
есть такое понятие upsert: сделать update на одну строку, и если этот update не затронул ни одну строку, сделать insert в ДРУГУЮ ВРЕМЕННУЮ ТАБЛИЧКУ ,когда ты справил свои нужды делаешь TRUNCATE TABLE своей временной таблички.

Пример upsert
SQL
1
2
3
4
5
6
7
UPDATE  my_table
 SET mast_id = :b1
 WHERE   ...
 IF SQL%NOTFOUND THEN
   INSERT INTO my_table
   VALUES ....
 END IF;
0
4 / 4 / 1
Регистрация: 03.12.2012
Сообщений: 55
25.02.2013, 18:56  [ТС]
Большое спасибо всем участникам, реализовал на эвентах оповещение о новых или измененных записях и выборкой только их. Но вот как узнать о удаленной записи? Ведь её уже нет, а если ставить флаг удаления то это уже получается модификация.
0
 Аватар для Oxotnuk
78 / 78 / 6
Регистрация: 18.06.2009
Сообщений: 533
25.02.2013, 19:03
Ну влюбом случае тебе нужно ведь где-то хранить,что такая запись ведь была....
Либо использовать встроенные средства АУДИТА сервера,но опять же, Аудит зачастую - и есть системная табличка,где можно отображать,кто,где,когда что-то изменил или сделал выборку.
0
4 / 4 / 1
Регистрация: 03.12.2012
Сообщений: 55
25.02.2013, 19:39  [ТС]
У меня при создании или редактировании в соответствующем поле ставится метка с помощью генератора, а при загрузки базы я узнаю максимальные значения и уже могу сделать выборку только измененных или созданных строк, а вот с удалением?
0
6 / 6 / 1
Регистрация: 01.06.2012
Сообщений: 107
26.02.2013, 08:39
А смотря где удаление. Создай некую корзину(таблицу), и будешь туда скидывать записи, из одной таблицы удалять в другую вставлять. Тем самым задача будет выполнена.
0
 Аватар для Oxotnuk
78 / 78 / 6
Регистрация: 18.06.2009
Сообщений: 533
26.02.2013, 12:24
doncelab, Я же говорю, ты работаешь с "флагом", тебе нужно же что-то инное, принцип "башен ханоя" в данном случае промежуточная таблица,то что у тебя есть сейчас,тебе прийдеться переделывать.
0
4 / 4 / 1
Регистрация: 03.12.2012
Сообщений: 55
26.02.2013, 18:57  [ТС]
Спасибо всем я реализовал все. Удаление сделал через триггер в UPDATE в котором определяется удаляю запись или изменяю. Удаляю через флаг, так как мне нужно оставлять удаленные записи.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.02.2013, 18:57
Помогаю со студенческими работами здесь

Использование глобальных переменных
Добрый всем день! Использую глобальную переменную для хранения значения в пределах одного сеанса работы программы. Например, текущий год...

Использование глобальных переменных
Доброго времени суток, уважаемые форумчане! Такой вопрос - почему использование глобальных переменных считается плохим тоном? Если дело...

Использование глобальных переменных - моветон ли?
Ребят, очень часто вижу как отцы С++, когда проверяют чей-то код и обнаруживают там глобальные переменные, заявляют, что это не хорошо, что...

Использование глобальных переменных объявленных в другом файле
Доброго времени суток. Столкнулся со следующей проблемой: Реализую некоторый алгоритм, состоящий из разных этапов. У алгоритма есть...

Исправить без использования глобальных переменных
#include&lt;iostream&gt; using namespace std; int a,n,maximum=-1000,x; void zapros() { cout&lt;&lt;&quot;Vvedite razmer massiva&quot;&lt;&lt;endl; } ...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru