Маленькие файлики записываются без проблем, хотя и подвисает операция вставки секунд на 5...
При попытке записать в БД бинарник большого размера (напр. около 30 мегабайт)...
q.prepare("select file_share.add_single_file(?, ?, ?, ?, ?, ?, null,?,?);");
QByteArray ba;
QFile file(getFilePath());
if (file.open(QIODevice::ReadOnly)){
ba = file.readAll();
file.close();
}
q.bindValue(0,ba,QSql::In|QSql::Binary); // Здесь все пучком
q.bindValue(1,getGroupID());
if (getInsurer() != 0) q.bindValue(2,getInsurer());
else q.bindValue(2,QVariant(QVariant::Int));
q.bindValue(3,getDescription());
q.bindValue(4,getFileName());
q.bindValue(5,getWWW());
q.bindValue(6,getCity());
q.bindValue(7,mask);
if (!q.exec()) { // тут виснет секунд на 30 и Unhandled exception at 0x1026f3e0 in project.exe: 0xC0000005: Access violation reading location 0xf272f6c4.
qDebug() << q.lastError() << q.executedQuery();
return false;
}
QString& QString::insert(int i, const QChar *unicode, int size)
{
if (i < 0 || size <= 0)
return *this;
const ushort *s = (const ushort *)unicode;
if (s >= d->data && s < d->data + d->alloc) {
// Part of me - take a copy
ushort *tmp = static_cast<ushort *>(qMalloc(size * sizeof(QChar)));
memcpy(tmp, s, size * sizeof(QChar));
insert(i, reinterpret_cast<const QChar *>(tmp), size);
qFree(tmp);
return *this;
}
expand(qMax(d->size, i) + size - 1);
::memmove(d->data + i + size, d->data + i, (d->size - i - size) * sizeof(QChar)); // <--- Эксепшн вылетает во время этой операции
memcpy(d->data + i, s, size * sizeof(QChar));
return *this;
}
QSqlDatabase db_b = QSqlDatabase::addDatabase("QPSQL", "b");
db_b.setHostName("10.10.1.123");
db_b.setPort(5433);
db_b.setDatabaseName("DBName");
db_b.setUserName("user");
db_b.setPassword("password");
вобще непонятно причем здесь QString. Вдь ты использушь двоичный масив и поидее должна вызыватся функция:
http://crossplatform.ru/documentation/qtdoc4.3/qsqlquery.php#bindValue-2в ней нет QString
Я незнаком с Постгре, но есть такая заметка:
Binary Large Objects (BLOB) are supported through the BYTEA field type in PostgreSQL server versions >= 7.1.
Может тебе понятно о чем речь?
select file_share.add_single_file(?, ?, ?, ?, ?, ?, null,?,?);
select file_share.add_single_file('\\134\\104\\134.........', 2, 3, 'Commentary is here...', 'file.bmp', true, null,1,0);
И к стати, ты не пробывал вызвать такую функцию:
db_b.driver().hasFeature (QSqlDriver::BLOB)
что он скажет, имеет драйвер такую возможность или нет?
Может она толком не реализована.
bool QSqlResult::exec()
{
bool ret;
// fake preparation - just replace the placeholders..
QString query = lastQuery();
if (d->binds == NamedBinding) {
int i;
QVariant val;
QString holder;
for (i = d->holders.count() - 1; i >= 0; --i) {
holder = d->holders.at(i).holderName;
val = d->values.value(d->indexes.value(holder));
QSqlField f(QLatin1String(""), val.type());
f.setValue(val);
query = query.replace(d->holders.at(i).holderPos,
holder.length(), driver()->formatValue(f));
}
} else {
QString val;
int i = 0;
int idx = 0;
for (idx = 0; idx < d->values.count(); ++idx) {
i = query.indexOf(QLatin1Char('?'), i);
if (i == -1)
continue;
QVariant var = d->values.value(idx);
QSqlField f(QLatin1String(""), var.type());
if (var.isNull())
f.clear();
else
f.setValue(var);
val = driver()->formatValue(f); // тут ненадолго задумывается....
query = query.replace(i, 1, driver()->formatValue(f)); // и тут вылетает ексепшн...
i += val.length();
}
}
// have to retain the original query with placeholders
QString orig = lastQuery();
ret = reset(query);
d->executedQuery = query;
setQuery(orig);
d->resetBindCount();
return ret;
}
::memmove(d->data + i + size, d->data + i, (d->size - i - size) * sizeof(QChar)); // <--- Эксепшн вылетает во время этой операции
::memmove(d->data + i + size, d->data + i, (d->size - size) * sizeof(QChar));
?Если верить этому коду, то Qt вместо параметров явным образом подставляет значения перед отправкой SQL-я на сервер.
А на длину SQL-я могут быть довольно сильные ограничения (Firebird/Interbase < 32к).
Если это так, то с лучше с базой работать сторонними либами, которые умеют работать с честными параметрическими запросами сервера...
Добрый день! столкнулся с полностью аналогичной проблемой. Есть ли какие-то способы решения?
использую qt 4.6.4, postgresql 8.4, visual studio 2008.
Может стоит обовиться? (и не поднимать темы 4-х летней давности...)
Qt 4.8.3, linux, firebird
100, 200 mb файлы хавает на раз
к сожалению использование Qt 4.6.4 требование заказчика, так что пляшем от чего имеем..
сделал добавление бинарников непосредственно через libpq
по сути сделал как в примере Example 30-3
http://www.postgresql.org/docs/8.4/static/libpq-example.html
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)