Russian Qt Forum
Сентябрь 30, 2024, 06:40 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QSqlDriver::formatValue и процедуры SQL  (Прочитано 6087 раз)
ритт
Гость
« : Ноябрь 21, 2007, 08:42 »

подозреваю, что средствами кути проблема не решается...но мало ли?

допустим, есть код (слегка покусано):
Код:
QVariantMap values;

//...

if(!values.value("TIMESTAMP_X").toDateTime().isValid())
values.insert("TIMESTAMP_X",  "now()");

//...

QSqlRecord rec = model()->record();
for(QVariantMap::ConstIterator it = values.constBegin(); it != values.constEnd(); ++it)
{
int fi = model()->fieldIndex(it.key());
if(fi >= 0)
rec.setValue(fi, it.value());
}

if(model()->insertRecord(-1, rec))
;// ну и дальше по смыслу...

//...
допустим, используем драйвер "QMYSQL"

смысл простой: получаем вариантмап значений, проводим незатейливую валидацию, перегоняем в рекорд и через модельку генерим запрос и скармливаем его субд

проблема тоже простая: при генерации запроса все поля рекорда проходят через QSqlDriver::formatValue и функция now() превращается в строку 'now()', что для поля типа скл датавремя есть NULL
собственно, любая функция превратится в её название, а дальше - в зависимости от типа ячейки...но сейчас интересует именно эта.

предвосхищая возможный ход мысли, значение поля по умолчанию (в таблице скл) использовать не хочется, т.к. знаение по "on update" можно проставить далеко не в каждом скл


пока вижу такие варианты: писать саггест и патч троллям; узнавать через запрос время на сервере и подставлять его значением вместо "now()" (с незначительной погрешностью в результате - особенно для отложенных запросов) - за неимением лучшего сейчас так и делаю;

возможно, кто-то уже сталкивался и придумал костыль (или даже патчик к кутям Улыбающийся )
« Последнее редактирование: Ноябрь 21, 2007, 09:09 от xep » Записан
ритт
Гость
« Ответ #1 : Ноябрь 22, 2007, 08:40 »

але...кто-нибудь ответит?
мне писать этот долбанный патч или оно нах никому не надо, а просто я один так удачно попал?
Записан
crocus
Гость
« Ответ #2 : Ноябрь 22, 2007, 11:19 »

Почитал внимательно про QSqlDriver::formatValue,  действительно функцию не загонишь, как вариант в рекорд подставлять не функцию БД, а дату например QDate::currentDate(), тебе же похоже все равно должно быть чем она сгенерируется Qt или БД раз ты сразу запись в модель вставляешь. Или можно через запрос c
Код:
model -> setQuery("INSERT.... SET my_date = CURDATE();")
так прекрасно работает или через bindValue (непробывал).
Записан
Вячеслав
Гость
« Ответ #3 : Ноябрь 22, 2007, 11:51 »

Почитал внимательно про QSqlDriver::formatValue,  действительно функцию не загонишь, как вариант в рекорд подставлять не функцию БД, а дату например QDate::currentDate(), тебе же похоже все равно должно быть чем она сгенерируется Qt или БД раз ты сразу запись в модель вставляешь. Или можно через запрос c
Код:
model -> setQuery("INSERT.... SET my_date = CURDATE();")
так прекрасно работает или через bindValue (непробывал).
Эта а откуда SET в INSERTE ? Это очепятка или я чего-то пропустил в SQL ?
Записан
crocus
Гость
« Ответ #4 : Ноябрь 22, 2007, 11:54 »

Пропустил  Смеющийся
Код:
13.2.4. INSERT Syntax
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    VALUES ({expr | DEFAULT},...),(...),...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

Or:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    SET col_name={expr | DEFAULT}, ...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

Or:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name [(col_name,...)]
    SELECT ...
    [ ON DUPLICATE KEY UPDATE col_name=expr, ... ]

 А, и это MySQL, в других БД не интересовался.
« Последнее редактирование: Ноябрь 22, 2007, 11:56 от crocus » Записан
ритт
Гость
« Ответ #5 : Ноябрь 22, 2007, 12:49 »

крокус,
в данный момент (пока я гоняю проект локально) мне всё-равно откуда упадёт датавремя, но в рабочей ситуации время на сервере может сильно отличаться от локального - в таком случае поиск по дате элемента сразу накрывается

генерить каждый запрос вручную - довольно извращённое занятие. особенно, при использовании скл-моделей, где в приватных методах через обёркти скл-драйвера  создаётся запрос под конкретную бд.
вытаскивать этот код из модели, модить и использовать в своих целях - тоже не лучший вариант, т.к. кутэшный код имеет тенденцию к изменениям, а у меня нет желания каждую новую версию сверять (уже был прецедент - до сих пор сверяю, т.к. разработчика некоегого продукта не интересуют мнения/потребности клиентов).

пару месяцев назад уже натыкался на бд-зависимый затык в склкверимодель и, дабы следовать своему пути, отписался троллям и приложил патчик для решения проблемы. теперь проблема зовётся "иссуя №183264" и имеет статус "решено"

в посте я описал как сейчас обхожу конкретно данный затык, но это не есть труъ...
причём, нов() - это лишь цветочки. по сути же, вообще никакие хп нельзя вызывать из нативных методов скл-моделей, т.к. обертка превращает их в строки...
например, uuid() мне сейчас таке приходится исполнять на стороне клиента

сейчас склоняюсь к мысли, что проще поступить примерно следующим образом:
создаю в кутэскл метатип, например, QSqlProcedureName aka QString и добавляю в обёртку QSqlDriver::formatValue проверку на этот тип. если в QSqlDriver::formatValue придёт вариант с типом QSqlProcedureName, будет возвращаться в запрос "как есть"
оформить это в виде патча и отправить с саггешшеном троллям

однако же, если это никому не нужно (вдруг, никто не использует хп с скл-моделями, кроме меня), пожалуй, откажусь от этой затеи и не буду тратить своё время
« Последнее редактирование: Ноябрь 22, 2007, 12:53 от xep » Записан
crocus
Гость
« Ответ #6 : Ноябрь 22, 2007, 13:29 »

Цитировать
генерить каждый запрос вручную - довольно извращённое занятие
Не лишено смысла, даже подтолкнул пересмотреть свой код Непонимающий
И вообще твое использование QVariantMap в этом контексте мне понравилось

А будет время патч все-таки сделай... совсем не лишне будет
Записан
Alex03
Гость
« Ответ #7 : Ноябрь 22, 2007, 13:31 »

Немного не по теме, но...
А триггеры в MySQL-е есть?
Я в FB в триггере before insert проверял поле на NULL и если надо заменял на текущее время.
Конечно если поле NOT NULL, иначе можно по другому но это уже точно изврат.
Записан
Вячеслав
Гость
« Ответ #8 : Ноябрь 22, 2007, 13:38 »

аффтор же сказал - тригерофф и updat'офф может и не быть Подмигивающий
А для птица все просто - и тригер и default Подмигивающий
Записан
ритт
Гость
« Ответ #9 : Ноябрь 22, 2007, 14:06 »

ага...в мускуле кажись до 4.1 не было on update
а недавно даже с трёшкой(!) пришлось столкнуться - там и default now() не срабатывал

если бы триггеры были во всех реализациях скл, проблем было бы меньше (по-крайней мере, таких)
но, в семье не без урода (про кутэодбц и говорить не хочется...)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.045 секунд. Запросов: 21.