powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Qt+firebird как правильно реализовать выборку >50 000 строк
25 сообщений из 26, страница 1 из 2
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37996995
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Собственно сабж. Если делать в лоб, т.е. с помощью QSqlQuery, валится на строке 36 064 возвращаемого результата.
QSqlModel подойдет для этой цели?
Спасибо.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37996996
magister_ludiСобственно сабж. Если делать в лоб, т.е. с помощью QSqlQuery, валится на строке 36 064 возвращаемого результата.
QSqlModel подойдет для этой цели?
Спасибо.
Какие название и номер ошибки?
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37997002
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
название и номер ошибкиmagister_ludiСобственно сабж. Если делать в лоб, т.е. с помощью QSqlQuery, валится на строке 36 064 возвращаемого результата.
QSqlModel подойдет для этой цели?
Спасибо.
Какие название и номер ошибки?

сигнал: sigsegv. назначение: segmentation fault.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37997094
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
magister_ludiсигнал: sigsegv. назначение: segmentation fault.

Разреши core dump, грузи его в gdb, смотри где и на чём оно упало.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37997114
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakovmagister_ludiсигнал: sigsegv. назначение: segmentation fault.

Разреши core dump, грузи его в gdb, смотри где и на чём оно упало.


дамп мало о чем сказал. вылетел на while(query.next()). Судя по стеку вызовов проблема в qt'шном драйвере для firebird, присутствует вызов QSqlCachedResult::cacheNext().
Драйвер устанавливался как пакет из репозитория Debian 6, командой apt-get install.
Были у кого такие проблемы? Как решали?
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37997124
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
magister_ludiвылетел на while(query.next()).
А ты уверен, что для этого цикла тебе требуется именно кэшированный датасет?.. Может,
обойдёшься таким, который не складывает полученные данные за щёку?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37997140
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakovmagister_ludiвылетел на while(query.next()).
А ты уверен, что для этого цикла тебе требуется именно кэшированный датасет?.. Может,
обойдёшься таким, который не складывает полученные данные за щёку?..


query->setForwardOnly(true)?
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37998969
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
magister_ludi..на строке 36 064 возвращаемого результата. ...

вот мне дико интересно, а что потом Вы будете делать с результатом то???

представил бесконечную бумажную ленту ползущую из принтера(типа убить бумагу, принтер, тонер в раз)...
Или файл отчёта для весу так сказать (типа у меня отчётов на 20 гигов!)?
Может быть Вы захотели всё втянуть "для скорости", и у вас самое крутое локальное железо? :)

короче говоря - просвятите дурака нахрена это делать то???

(круглый)
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37999059
vvm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolobok0,

Назови, пожалуйста, нижнюю границу обёма выборки, до которой ты бы не стал поднимать свой вопрос.
Спасибо. :)
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37999099
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
magister_ludiприсутствует вызов QSqlCachedResult::cacheNext().
Скорее всего ты упёрся в лимит объёма этого Кешированного ДатаСета.
Читай документацию. Да и вообще, знающие верно подметили
что прогружать всю базу на клиента это не cool. Соптимизируй
объём.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #37999223
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvmkolobok0,

Назови, пожалуйста, нижнюю границу обёма выборки, до которой ты бы не стал поднимать свой вопрос.
Спасибо. :)
2-3 экрана записей
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38000280
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kolobok0magister_ludi..на строке 36 064 возвращаемого результата. ...

короче говоря - просвятите дурака нахрена это делать то???

(круглый)

Специализированная программа для создания файлов конфигурации графа технического состояния промышленного комплекса. Не я это придумал, да.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38000324
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
maytonmagister_ludiприсутствует вызов QSqlCachedResult::cacheNext().
Да и вообще, знающие верно подметили
что прогружать всю базу на клиента это не cool. Соптимизируй
объём.

Все верно, это я понимаю. Ситуация стандартна: кто-то эту жесть придумал, другой написал и уволился, а третий со всем этим гумном разбирается. И вот в текущей ситуации, кроме как делать выборку по всем записям, ничего сделать нельзя. Благо база локальная.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38000578
rovan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сделай setForwardOnly(true), и, раз уж не обойтись без предварительного кэширования, начитывай данные в свои струтуры. И храни в своих структурах. Так, хотя бы, сможешь управлять процессом начитки и кеширования.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38001585
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rovanСделай setForwardOnly(true), и, раз уж не обойтись без предварительного кэширования, начитывай данные в свои струтуры. И храни в своих структурах. Так, хотя бы, сможешь управлять процессом начитки и кеширования.

так и делаю. результат такой же: segmentation fault
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
               QSqlQuery* query = new QSqlQuery(this->dbss);              
               QString queryString = "SELECT FIRST %1 SKIP %2 * FROM SAVE_ADDRS";
               query->setForwardOnly(true);
              //формирование строки запроса не привожу
               if (query->exec(queryStringWithArgs))
               {
                   while(query->next())
                   {
                       //тут действия с данными
                       //где-то на записи 36 066 ломается
                   }
               }
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38001589
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
magister_ludi,

А есть segfault если закомментарить тело цикла?
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38001593
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
magister_ludiформирование строки запроса не привожу

И кстати зря не приводите, т.к. в коде форматирующем строки часто бывают ошибки переполнения буфера. А они в свою очередь прямо ведут к segfault в произвольных местах программы.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38001601
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskymagister_ludi,

А есть segfault если закомментарить тело цикла?

все работает
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38001607
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovskymagister_ludiформирование строки запроса не привожу

И кстати зря не приводите, т.к. в коде форматирующем строки часто бывают ошибки переполнения буфера. А они в свою очередь прямо ведут к segfault в произвольных местах программы.

Почему я не стал писать формироание строки запроса. Изначально запрос был таким:
Код: plsql
1.
SELECT * FROM SAVE_ADDRS



Это уже потом начал подгружать данные порциями в надежде победить ошибку и все равно результата нет.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38001632
rovan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
magister_ludiПочему я не стал писать формироание строки запроса. Изначально запрос был таким:

Так а сейчас он какой?
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38002326
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
magister_ludiAnatoly Moskovskymagister_ludi,

А есть segfault если закомментарить тело цикла?

все работает
Ну так как вы нам тогда предлагаете гадать из-за чего ошибка, если не приведен код вызывающий ее?
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38003280
magister_ludi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Извиняюсь. Вот код:
Код: plaintext
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.
74.
75.
76.
77.
78.
79.
80.
unsigned long *buff/*буфер*/, i, n/*позиция в буфере*/, num /*число символов на запись*/;
    i = 0; n = 0; 
    QString s;
    buff = NULL;

       if (this->dbss.open())
       {
               QSqlQuery query;
               QString queryString = "SELECT * FROM SAVE_ADDRS";
               query.setForwardOnly(true);

               if (query.exec(queryString))
               {

                   while(query.next())
                   {
                       if (query.at() == 0)
                       {
                           //из первой строки берем кол-во записей
                           if (query.value(0).toInt() !=1)
                               return;
                           *cnt = query.value(1).toInt();//кол-во записей
                           i++;
                           continue;

                       }
                       if (query.at() == 1)
                       {
                            //из второй размер буфера
                            if (query.value(0).toInt() !=2)
                                return;
                            *size = *cnt + query.value(1).toInt();//размер буфера
                            buff = (long unsigned int*)malloc(*size);
                            _mem = (void*)buff;
                            n++;
                            if (buff == NULL)
                                return;
                            i++;
                            continue;

                       }
                       if ((query.at() > 1)&&(query.value(0).toInt() !=0))
                       {
                           return;
                       }
                       if (i ==(*cnt))
                       {
                           break;
                       }

                       if (query.value(2).isNull())
                       {
                           buff = 0;
                           n++;
                       }
                       else
                       {
                         s = query.value(2).toString().trimmed();
                         const char* sourceString = s.toAscii().constData();
                         num =s.size();
                          //если копирование в буфер убрать, то все работает.
                          memcpy(&buff[n], sourceString,num);
                          n+=num;
                          buff[n]=0;
                          n++;
                          i++;
                          qDebug()<< i << sourceString;
                       }


                   }
           int writeResult = fwrite((void *)buff, *size, 1, _ofile);
           free(buff); _mem = NULL;
           if(writeResult != 1)
           {
               qDebug() << "error write data to file";
           }
       }

}
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38003303
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
magister_ludi,

Обратите внимание на этот код
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
if (query.value(2).isNull())
                       {
                           buff = 0;
                           ...
                       }
                       else
                       {
                           ...
                          //если копирование в буфер убрать, то все работает.
                          memcpy(&buff[n], sourceString,num);
                           ...
                       }


Т.е. у вас, если в очередной записи встретился null в поле №2, то указатель на буфер обнуляется, и на следующей итерации цикла где не будет null, memcpy затрет память около нулевого адреса (а эта страница всегда защищена от записи - отсюда и сегфолт).

Ну и обнуление указателя на буфер делает бессмысленным free() в конце цикла.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38003309
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и так тоже нельзя делать:
Код: plaintext
1.
const char* sourceString = s.toAscii().constData();


- т.к. здесь вы в указатель записываете адрес временной переменной, которая будет удалена до того как вы этим указателем воспольуетесь.

Правильно так:
Код: plaintext
1.
2.
XXXX tmp_s = s.toAscii(); // теперь время жизни tmp_s больше чем sourceString
const char* sourceString = tmp_s.constData();


Вместо XXX поставьте тип который возвращает toAscii() (я его не знаю, см. доку)

Это ошибка тоже может приводить к сегфолту. Но думаю что до нее не доходит, т.к. срабатывает гарантированный сегфолт описанный в моем предыдущем сообщении.
...
Рейтинг: 0 / 0
Qt+firebird как правильно реализовать выборку >50 000 строк
    #38003315
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И еще.

У вас объявлено
Код: plaintext
1.
unsigned long *buff

, т.е. указатель на массив элементов размера 4 или 8 байтов.
А в коде вы к нему обращаетесь как к указателю на байты (char *buff).
Код: plaintext
1.
2.
3.
memcpy(&buff[n], sourceString,num);  // num - размер строки в байтах
n+=num; // но n в следующецй строке индексирует элементы размером в несколько байтов, прибавлять к нему байты некорректно 
buff[n]=0;


Это неминуемое переполнение буфера.
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Qt+firebird как правильно реализовать выборку >50 000 строк
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]