Russian Qt Forum

Qt => Базы данных => Тема начата: varkon от Июль 04, 2010, 23:29



Название: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 04, 2010, 23:29
Подскажите пожалуста. Есть такой код, задача которого - изменить значение генератора в БД.

Код:
int dmModule::setGenGoods(const int gen){
    QString query_str = "SET GENERATOR GEN_SPRGOODS_ID TO ?";
    QSqlQuery *query = new QSqlQuery(dmModule::db);
    query->prepare(query_str);
    query->addBindValue(gen);
    query->setForwardOnly(true);
    query->exec();
    if(query->lastError().isValid()){
        QMessageBox::about(0,"errror",query->lastError().text()+query->lastQuery());
    }
    dmModule::db.commit();
    delete query;
    return 0;

}

код вызывается и нормально отрабатывает. Но значение генератора остается прежним.
В IBExpert используя SQL Editor данный запрос удается выполнить без проблем.
Почему не выполняется в функции?


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: lit-uriy от Июль 05, 2010, 00:32
а где начало транзакции?


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 05, 2010, 17:31
а без разницы. что с началом что без.
Код:
//объявлено соединение статически в классе предке
//начали транзакцию
 dmBaseModule::db.transaction();
    QString query_str = "SET GENERATOR GEN_SPRGOODS_ID TO ?";
    QSqlQuery *query = new QSqlQuery(dmBaseModule::db);
    query->prepare(query_str);
    query->addBindValue(gen);
    query->setForwardOnly(true);
    query->exec();
    if(query->lastError().isValid()){
        QMessageBox::about(0,"errror",query->lastError().text()+query->lastQuery());
    }
//тут вроде коммит
    dmBaseModule::db.commit();


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: sarbash от Июль 06, 2010, 10:09
Чем проверяется значение генератора после отработки функции?


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 06, 2010, 12:33
Проверяется его значение, которое должно быть установлено.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: lit-uriy от Июль 06, 2010, 13:01
>>Проверяется его значение
вопрос как раз "чем?" проверяется.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 06, 2010, 13:15
>>Проверяется его значение
вопрос как раз "чем?" проверяется.
ну например вызов gen_id должен вернуть как минимум на единицу большее значение чем установленное (с БД работает один клиент). Можно конечно установить генератор банально
Код:
select gen_id(gen_sprgoods_id,1) from sometable

например. Но это как то не по человечески имхо


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: sarbash от Июль 06, 2010, 13:43
Если по-другому не получается, придётся установить генератор банально. :)
Здесь есть хороший драйвер на основе ibpp, не сочтите за рекламу, но могу порекомендовать. Использую именно его, проблем нету. В том числе и с установкой значения генератора.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 07, 2010, 08:13
хорошо.
А можно привести пример - как вы устанавливаете значение генератора?
Я скомпилировал драйвер, и теперь получаю ошибку. Это конечно лучше, чем ничего :) но однако же  - почему не выполняется код?
Сообщение о ошибке:


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: sarbash от Июль 07, 2010, 08:39
Откровенно говоря, специально не приходилось вручную устанавливать генераторы, они у меня при добавлении записей триггерами дёргаются. Но исходя из текста ошибки, скорее всего с биндингом проблема. А если "?" поменять на что-то типа ":GEN_VAL" и забиндить к нему? Та же ошибка?


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 07, 2010, 09:08
Откровенно говоря, специально не приходилось вручную устанавливать генераторы,
Цитата: sarbash
Использую именно его, проблем нету. В том числе и с установкой значения генератора.
гммм.  ;D ладно проехали.

Но исходя из текста ошибки, скорее всего с биндингом проблема. А если "?" поменять на что-то типа ":GEN_VAL" и забиндить к нему? Та же ошибка?
Да. Ошибка та же - естественно отображается только не "?" а забинденное значение. Вероятно тут проблема не с биндингом как таковым, а с биндингом конкретных инструкций? Хз. Ведь прочие запросы у меня все пользуются исключительно параметрами - и вроде пока работают? В общем непонятка. Возможно баг. Задам вопрос на гуглокоде. Я так полагаю, что проблема была не в том, что QIBASE-драйвер этого не может. Проблема вероятно в том - что он (драйвер в смысле) очень молчалив. :) Как утверждают на словарике (http://firebirdsql.su/doku.php?id=set_generator) данная конструкция этой версией сервера(2.1) поддерживаться не должна. Типа устарела. Специально проверю, но немного позже. Пока работает такой код (для рекламируемого дравера :) )
Код:
int dmModule::setGenGoods(const int gen){
     dmBaseModule::db.transaction();
     QString query_str = "ALTER SEQUENCE GEN_SPRGOODS_ID RESTART WITH "+QString::number(gen);

    QSqlQuery *query = new QSqlQuery(dmBaseModule::db);
   // query->prepare(query_str);
   // query->addBindValue(gen);
    if(!query->exec(query_str)){
        QMessageBox::about(0,"errror",query->lastError().text()+query->lastQuery());
        dmBaseModule::db.rollback();
        delete query;
        return 0;
    }
    dmBaseModule::db.commit();
    delete query;
    return 1;

}

но то что с параметрами работать не хочет - это не есть гут.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: lit-uriy от Июль 07, 2010, 09:24
вообще установка генератора в конкретное значение не рекомендуется, иначе смысл генератора теряется


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: sarbash от Июль 07, 2010, 10:22
Про установку значения генератора я подразумевал успешный тест запроса. Одно большое но -- биндинг значения в запросе я не проверял, использовал простой запрос без prepare. Отсюда и предположение. Данная конструкция версией 2.1 поддерживается, именно эту версию я и использую.

lit-uriy прав, для генерации первичных ключей генератор должен дёргаться триггером. Если только его использовать не по прямому назначению, а для каких-то других целей...


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: sarbash от Июль 07, 2010, 10:56
Вскрытие показало, на данный тип квери ("SET GENERATOR GEN_NAME TO ?") биндинг не работает. По-видимому, причина сокрыта где-то в недрах QSqlQuery.
Если данный функционал жизненно необходим, могу посоветовать запостить багрепорт.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 07, 2010, 12:22
вообще установка генератора в конкретное значение не рекомендуется, иначе смысл генератора теряется
на самом деле все это зависит от задач. У меня генератор дергается из процедуры - но согласно ТО у пользователя должна быть возможность идентификатор товара (код которого собственно и продуцирует генератор) задать руками - это организационно-производственные причины  - и в данном случае требование вполне обоснованное (+ это РБД - и далеко не факт, что мне самому не придется корректировать значение последовательности). Соответственно необходимо бы дать возможность устанавливать значение от которого далее будут генерироваться номера.
Цитировать
Вскрытие показало, на данный тип квери
речь идет вообще о DDL-запросах? Но впрочем буду еще разбираться.
Спасибо за внимание. В любом случае проблема решена.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: MoPDoBoPoT от Июль 07, 2010, 14:44
Связывание переменных разрешено только в DML, ведь это не просто тупое подставление значния в текст запроса.
Кстати, на операторы DDL команды управления транзакциями не распространяются. Не знаю как в InterBase, но в Oracle после каждого DDL-оператора происходит неявный commit.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 07, 2010, 15:10
Ну что ж, может быть логика в этом есть.
По поводу транзакций  - а собственно почему должен быть неявный коммит?


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: lit-uriy от Июль 07, 2010, 15:44
>>на операторы DDL команды управления транзакциями не распространяются
В Firebird всё тоже самое. Генераторы не затрагиваются транзакциями. Сама концепция генераторов этого не допускает.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 07, 2010, 16:14
>>на операторы DDL команды управления транзакциями не распространяются
В Firebird всё тоже самое. Генераторы не затрагиваются транзакциями. Сама концепция генераторов этого не допускает.
да. использование транзакций в моем коде лишнее.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: MoPDoBoPoT от Июль 07, 2010, 16:28
Кстати, на операторы DDL команды управления транзакциями не распространяются.
Прошу прощения за категоричность. В некоторых СУБД (например, DB2) возможно использование DDL-операторов внутри транзакций.


Название: Re: [Qt+Firebird] Изменить значение генератора из клиента
Отправлено: varkon от Июль 07, 2010, 17:07
Описал решение на своем сайте, со ссылкой на данное обсуждение - [Qt+Firebird] Как установить начальное значение генератора/последовательности из клиента (http://varkon.biz/?q=qt_firebird_sequence)
Всем огромное спасибо за помощь.