Форум программистов, компьютерный форум, киберфорум
C++ Builder: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
2 / 2 / 1
Регистрация: 30.03.2009
Сообщений: 61

Цикл для обновления данных в БД

07.06.2012, 02:05. Показов 1248. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброй ночи. В таблице есть поле "raiting" который необходимо подсчитать по нажатию кнопки.
Алгоритм подсчтета прост: сначала считаем общую сумму заказов, затем сумму заказов каждого магазина в отдельности и делим на общую сумму. Для данной операции использовал цикл while. Ошибок не было, приложение просто виснет после подсчета рейтинга для первого магазина.
Не совсем понимаю в чем может быть причина. Может кто подсказать? Спасибо.

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
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//расчет общей суммы заказов
float b=0;
DataModule1->forchart->Close();
DataModule1->forchart->SQL->Clear();
DataModule1->forchart->SQL->Text="select SUM(price) as B from Orders";
DataModule1->forchart->Open();
b=DataModule1->forchart->FieldByName("B")->AsInteger;
FormatFloat("0.00",b);
 
while (!DataModule1->ADOTable1->Eof)
{
//подсчет суммы заказов магазина где id=t
float a=0; 
int t=1;
DataModule1->forchart->Close();
DataModule1->forchart->SQL->Clear();
DataModule1->forchart->SQL->Text="select SUM(price) as A from Orders where id_shop=:t";
DataModule1->forchart->Open();
a=DataModule1->forchart->FieldByName("A")->AsInteger;
FormatFloat("0.00",a);
//вставка полученного значения в таблицу
DataModule1->forchart->Close();
DataModule1->forchart->SQL->Clear();
DataModule1->forchart->SQL->Text="update Shop set raiting='"+FormatFloat("0.00",a/b)+"' where id_shop=:t";
DataModule1->ADOTable1->Active=false;
DataModule1->ADOTable1->Active=true;
 
t++; 
DataModule1->ADOTable1->Next();
}
}
БД на MS SQL 2005.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.06.2012, 02:05
Ответы с готовыми решениями:

Как создать цикл для обновления картинки в TImage?
Здравствуйте. Создал форму,на неё поставил TImage,на неё процедура: procedure TForm2.Image1Click(Sender: TObject); begin ...

Где скачать обновления для AVG Internet Security для обновления в оффлайн режиме?
Сабж.

Макрос для обновления данных в столбцах
Всем добрый день! Я только начинаю разбирать VBA,по этому следующая задачу, которую я опишу, для меня не посильная на данный момент(а...

12
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
07.06.2012, 02:22
SlimFIT, а сам проект можно посмотреть?

Добавлено через 2 минуты
Цитата Сообщение от SlimFIT Посмотреть сообщение
БД на MS SQL 2005.
Блин... Не заметил
C++
1
DataModule1->ADOTable1->Active=true;
После этого курсор переходит в самое начало ADOTable1.
0
2 / 2 / 1
Регистрация: 30.03.2009
Сообщений: 61
07.06.2012, 02:25  [ТС]
Цитата Сообщение от The_Immortal Посмотреть сообщение
сам проект можно посмотреть?
Выложить полностью или что-то конкрентое?
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
07.06.2012, 02:31
SlimFIT,
Цитата Сообщение от SlimFIT Посмотреть сообщение
В таблице есть поле "raiting" который необходимо подсчитать по нажатию кнопки.
И, кстати, такие вещи лучше делать по событию Тейбла - OnCalcFields();
Ступил. Вам же рейтинг потом надо в самой БД обязательно хранить, да?

Добавлено через 1 минуту

Цитата Сообщение от SlimFIT Посмотреть сообщение
Выложить полностью или что-то конкрентое?
Да не, с MS SQL не надо выкладывать, у меня его нету все равно

Добавлено через 2 минуты
И все-таки поясните необходимость делать вот это в цикле:
Цитата Сообщение от SlimFIT Посмотреть сообщение
C++
1
2
DataModule1->ADOTable1->Active=false; 
DataModule1->ADOTable1->Active=true;


Цитата Сообщение от SlimFIT Посмотреть сообщение
//подсчет суммы заказов магазина где id=t
Хм...И "id" какой у нас тип поля? Не автоинкремент случайно?
1
2 / 2 / 1
Регистрация: 30.03.2009
Сообщений: 61
07.06.2012, 02:33  [ТС]
Забыл поставить ExecSQL();
C++
1
2
DataModule1->forchart->SQL->Text="update Shop set raiting='"+FormatFloat("0.00",a/b)+"' where id_shop=:t";
DataModule1->forchart->ExecSQL();
Закоментировал строки
C++
1
2
DataModule1->ADOTable1->Active=false;
DataModule1->ADOTable1->Active=true;
Цикл проходит, но данные не подсчитывает...
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
07.06.2012, 02:36
А вот это?
Цитата Сообщение от The_Immortal Посмотреть сообщение
Хм...И "id" какой у нас тип поля? Не автоинкремент случайно?
"id_shop" имел в виду
0
2 / 2 / 1
Регистрация: 30.03.2009
Сообщений: 61
07.06.2012, 02:36  [ТС]
Цитата Сообщение от The_Immortal Посмотреть сообщение
И, кстати, такие вещи лучше делать по событию Тейбла - OnCalcFields();
Ступил. Вам же рейтинг потом надо в самой БД обязательно хранить, да?

Хм...И "id" какой у нас тип поля? Не автоинкремент случайно?
Да, подсчитанный рейтинг надо сохранить в БД.
Поле id автоинкремент.
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
07.06.2012, 03:51
SlimFIT,

Цитата Сообщение от SlimFIT Посмотреть сообщение
Поле id автоинкремент.
Тогда так id подсчитывать нельзя. Его надо получать.

Выслал Вам предложение в ПМ.

Добавлено через 1 час 11 минут
Ну вроде решили траблу
0
2 / 2 / 1
Регистрация: 30.03.2009
Сообщений: 61
07.06.2012, 04:01  [ТС]
Решение проблемы. Возможно кому-нибудь еще пригодится.
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
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float b=0;
DataModule1->forchart->Close();
DataModule1->forchart->SQL->Clear();
DataModule1->forchart->SQL->Text="select SUM(price) as B from Orders";
DataModule1->forchart->Open();
b=DataModule1->forchart->FieldByName("B")->AsFloat;
FormatFloat("0.00",b);
int t=0;
bool stop=false;
 
DataModule1->ADOQuery8->Close();
DataModule1->ADOQuery8->SQL->Clear();
DataModule1->ADOQuery8->SQL->Text="select o.id_shop from Orders o, Shop sh where sh.id_shop=o.id_shop group by o.id_shop";
DataModule1->ADOQuery8->Open();
 
while (!DataModule1->ADOTable1->Eof)
{
float a=0.00;
 if (DataModule1->ADOQuery8->RecordCount!=0) {
        if (!stop) {t=DataModule1->ADOQuery8->FieldByName("id_shop")->AsInteger;
 
DataModule1->forchart->Close();
DataModule1->forchart->SQL->Clear();
DataModule1->forchart->SQL->Text="select SUM(price) as A from Orders where id_shop=" + IntToStr(t);
DataModule1->forchart->Open();
a=DataModule1->forchart->FieldByName("A")->AsFloat;
FormatFloat("0.00",a);
        }
        else {a=0.00;
                FormatFloat("0.00",a);
                }
                }
else {a=0.00;
FormatFloat("0.00",a); }
 
DataModule1->forchart->Close();
DataModule1->forchart->SQL->Clear();
DataModule1->forchart->SQL->Text="update Shop set raiting='"+FormatFloat("0.00",a/b)+"' where id_shop=" + DataModule1->ADOTable1->FieldByName("id_shop")->AsInteger;
//DataModule1->forchart->SQL->Text="update Shop set raiting="+FormatFloat("0.00",a/b);
DataModule1->forchart->ExecSQL();
 
//t++;
DataModule1->ADOTable1->Next();
DataModule1->ADOQuery8->Next();
if (DataModule1->ADOQuery8->Eof) stop = true;
}
DataModule1->ADOTable1->Active=false;
DataModule1->ADOTable1->Active=true;
}
1
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
07.06.2012, 04:54
Кстати, кто-нибудь может объяснить вот этот момент:

C++
1
"update Shop set raiting='"+FormatFloat("0.00",a/b)+"' ...
Почему-то когда a=0, b=510.256 (любое действительное значение), то в raiting помещается '0', а не '0.00'.

Подскажите, пожалуйста, в чем тут дело?

Добавлено через 1 минуту
SlimFIT, кстати, а raiting-то у Вас какого типа?
Наверное, оно числовое с форматом действительных чисел, да? Тогда пожалуй надо убрать одинарные кавычки на добавление в raiting и в MS SQL выставить формат "0.00" на это поле. Тогда 0.00 по идее норм будет отображаться.
А все
C++
1
FormatFloat("0.00",a);
убрать.
0
2 / 2 / 1
Регистрация: 30.03.2009
Сообщений: 61
07.06.2012, 18:56  [ТС]
Да, поле "raiting" формата Float. В настройках не вижу где можно изменить формат отображения на "0.00".
Одинарные кавычки убрал, закоментил строки
C++
1
FormatFloat("0.00",a);
Все работает как надо.

Добавлено через 38 минут
Во время тестирования обнаружил, что считает рейтинг правильно, но значение присваивает не корректно. Поясню на примере.
У магазинов 1,2,3,4 ... рейтинг 0.5, 0.5, 0, 0 ... соответственно. Добавляю заказ для 4 магазина, жму пересчет. По логике рейтинг поменяется у всех кроме 3 (у него нет заказов). Программа считает, и рейтинг присваивает первым 3 магазинам. Получется что рейтинг, который должен быть присвоен магазину 4, по факту присваивается магазину 3.
Может цикл написан не так? Где ошибка?
0
2 / 2 / 1
Регистрация: 30.03.2009
Сообщений: 61
09.06.2012, 01:25  [ТС]
Нашел ошибку в расчете. Проверил, считает как положено и все абсолютно верно.
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
DataModule1->ADOTable1->First();
float b=0;
DataModule1->forchart->Close();
DataModule1->forchart->SQL->Clear();
DataModule1->forchart->SQL->Text="select SUM(price) as B from Orders";
DataModule1->forchart->Open();
b=DataModule1->forchart->FieldByName("B")->AsFloat;
FormatFloat("0.00",b);
 
int t=0;
bool stop=false;
 
DataModule1->ADOQuery8->Close();
DataModule1->ADOQuery8->SQL->Clear();
DataModule1->ADOQuery8->SQL->Text="select o.id_shop from Orders o, Shop sh where sh.id_shop=o.id_shop group by o.id_shop";
DataModule1->ADOQuery8->Open();
 
while (!DataModule1->ADOTable1->Eof)
{
float a=0.00;
        if (DataModule1->ADOQuery8->RecordCount!=0)
        {
                if (!stop)
                {
                        t=DataModule1->ADOQuery8->FieldByName("id_shop")->AsInteger;
                        DataModule1->forchart->Close();
                        DataModule1->forchart->SQL->Clear();
                        DataModule1->forchart->SQL->Text="select SUM(price) as A from Orders where id_shop=" + IntToStr(t);
                        DataModule1->forchart->Open();
                        a=DataModule1->forchart->FieldByName("A")->AsFloat;
                        FormatFloat("0.00",a);
                }
                else {a=0.00;
                        FormatFloat("0.00",a);
                     }
        }
        else {a=0.00; FormatFloat("0.00",a);
              }
DataModule1->forchart->Close();
DataModule1->forchart->SQL->Clear();
DataModule1->forchart->SQL->Text="update Shop set raiting='"+FormatFloat("0.00",a/b)+"' where id_shop="+IntToStr(t);
DataModule1->forchart->ExecSQL();
 
DataModule1->ADOTable1->Next();
DataModule1->ADOQuery8->Next();
 
}
DataModule1->ADOTable1->Active=false;
DataModule1->ADOTable1->Active=true;
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
09.06.2012, 02:08
SlimFIT, ну слава Богу
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.06.2012, 02:08
Помогаю со студенческими работами здесь

Скрипт для обновления данных в таблице
Есть тестовый файл. Нужен PHP скрипт, который будет выполнять обновление данных в столбце "price" таблицы "oc_product"...

Запрос на сайт для обновления своих данных.
Проблема заключается в том, что необходимо все время обновлять данные на своем сайте, связанные с котировкой валют, для этого необходимо...

Создание форм для добавления/обновления данных
Всем добрый день. Решил написать под себя простенькую БД заказов и проплат, так как наша офисная - на китайском и я ничего в ней не...

Где происходит обработка данных для вставки (обновления)?
У нас есть серверная служба и есть клиентская программа. Где должен быть запрос на вставку(обновление,удаление) данных в самом запросе с...

Как создать DataAdapter для возможности сохранения (обновления) данных
Делаю так, отдельной процедурой гружу таблицы в Dataset: Private Sub LoadTable(ByVal TableName As String) Dim DA As New...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера 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. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru