Russian Qt Forum

Qt => Базы данных => Тема начата: Я.К. от Май 30, 2009, 20:10



Название: препарированный запрос, bindValue(...)
Отправлено: Я.К. от Май 30, 2009, 20:10
Создается запрос к базе:
Код:
void Base::AddTrack(Track& newTrack)
{

QSqlQuery mainTrackQuery(db);//всвтавка в таблицу треков
QString mainQueryString("INSERT INTO Tracks( :title, :path ) \
VALUES( :titleV,  :pathV)");

mainTrackQuery.exec();


if(newTrack.path == "")
{
mainQueryString.remove(":path,");
mainQueryString.remove(":pathV,");
}
else
{

mainQueryString.replace(":pathV", "SELECT id FROM Genres WHERE value = :pathV");
}

if(newTrack.title == "")
{
mainQueryString.remove(":tetle,");
mainQueryString.remove(":tetleV,");
}
else
{

mainQueryString.replace(":titleV", "SELECT id FROM Titles WHERE value = :titleV");
}


//вставка значений в строку запроса!

mainTrackQuery.prepare(mainQueryString);

mainTrackQuery.bindValue(":path", "pathId");
mainTrackQuery.bindValue(":pathV", newTrack.path);
mainTrackQuery.bindValue(":title", "titleId");
mainTrackQuery.bindValue(":titleV", newTrack.title);
cout <<mainTrackQuery.exec()<<endl;
cout <<"MEGATRACK_"<< mainTrackQuery.lastError().text().toStdString()<<endl;
cout << mainTrackQuery.executedQuery().toStdString()<<endl;

}

По итогам: происходит следующее:
mainTrackQuery.exec() возвращает 0,
mainTrackQuery.lastError().text() возвращает "Parameter count mismatch"


lastExecutedQuery дает вот что:

Код:
INSERT INTO Tracks(, ?, ? )
                VALUES( SELECT id FROM Tit
les WHERE value = ?, SELECT id FROM Paths WHERE value = ?)
Последнее как раз нареканий вроде бы вызывать и не должно, так как в SQLITE эти параметры должны были передаваться отдельно.
Но все-таки, как с таким бороться?
Или как обойтись без препарированных запросов, чтобы, например, корректно сохранять в базу пути со знаком << ' >>, например?


Название: Re: препарированный запрос, bindValue(...)
Отправлено: Rcus от Май 30, 2009, 20:54
Никогда бы не подумал что можно параметризовать запрос названиями полей, а от вон оно как...
Еще запятых что-то слишком много в lastExecutedQuery()


Название: Re: препарированный запрос, bindValue(...)
Отправлено: lit-uriy от Май 30, 2009, 21:40
Код
C++ (Qt)
Tracks( :title, :path )
VALUES( :titleV,  :pathV)
и
Код
C++ (Qt)
mainQueryString.remove(":path,");
mainQueryString.remove(":pathV,");
запятые почему в конце?


Название: Re: препарированный запрос, bindValue(...)
Отправлено: BOBO4KA от Май 31, 2009, 00:20
lastExecutedQuery дает вот что:

Код:
INSERT INTO Tracks(, ?, ? )
                VALUES( SELECT id FROM Tit
les WHERE value = ?, SELECT id FROM Paths WHERE value = ?)

Правильно ругается)
Пытаешся записать в таблицу 3 значения а выбираеш только 2.
Разберись с формированием имен полей, а вобще лучше делай их одинаковыми.


Название: Re: препарированный запрос, bindValue(...)
Отправлено: mugabe от Июнь 01, 2009, 06:12
Извиняюсь за грубость, но что там вообще за каша из бреда?

В строке :path и :pathV без запятых - удалять пытаемся с запятыми. Не говоря уже о том что так в принципе делать не совсем правильно.
Подставлять название поля в качестве параметра - тоже какой-то бред. Большинство СУБД такое не пропустят.
Тем более что вы в любом случае указываете строго заданное значение.
Если это пропускает SQLITE - ну что, же, я рад за его возможности, но становится не совсем понятным вообще смысл поддержки такой параметризации.

В строке :title, а удаляем :tetle.

И я, конечно, мало знаком с диалектом SQLITE, но не совсем уверен, что такое он вообще сможет корректно выполнить:
Код:
... VALUES( SELECT id FROM Titles WHERE value = ?, SELECT id FROM Paths WHERE value = ?)


Вы сами хотя бы прочитайте написанный вами код. По-моему надо обладать большим везением, что бы вообще скомпилировать что-то, делая столько ошибок.


Название: Re: препарированный запрос, bindValue(...)
Отправлено: lit-uriy от Июнь 01, 2009, 07:21
Нда, такой вроде небольшой код, а уже столько замечаний.

Я.К., ты поди его на ночь глядя писал - гиблое это дело.