crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

3 страниц V  < 1 2 3 >  
Ответить в данную темуНачать новую тему
> Отображение BLOB полей таблиц БД FireBird в QTableView Qt в Windows
Steklova Olga
  опции профиля:
сообщение 15.3.2012, 20:07
Сообщение #11


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Раньше, в пункте 7. делала так:
Цитата
Вставила в таблицу T_MSG записи (с номерами 3 и 4) с BLOB в коде программы с помощью QSqlQuery:
QString query_str;
QSqlQuery query;
query_str = "INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B) "
  "VALUES (3, 'PRIVET3: ПРИВЕТ3', 'PRIVET3: ПРИВЕТ3')";
query.exec(query_str);
query_str = "INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B) "
  "VALUES (4, 'PRIVET4: ПРИВЕТ4', 'PRIVET4: ПРИВЕТ4')";
query.exec(query_str);

Теперь вместо этого
14. Попробовала использовать подготовленный запрос:
    if (!query.prepare("INSERT INTO T_MSG "
                  "(F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B) "
                  "VALUES (:F_RECORD_NMB, :F_MSG_TEXT_VC, :F_MSG_TEXT_B)")) {
        qDebug() << "не удалось успешно подготовить запрос";
        return 1;
    }
    query.bindValue(":F_RECORD_NMB", 7);
    query.bindValue(":F_MSG_TEXT_VC", "PRIVET7: ПРИВЕТ7");
    query.bindValue(":F_MSG_TEXT_B", "PRIVET7: ПРИВЕТ7");
    query.exec();
    if (!query.isActive()) {
        qDebug() << "не удалось успешно выполнить запрос:"
                << query.lastError().text();
        return 2;
    }

И вот, после выполнения query.exec() ВЫЛЕЗЛА ОШИБКА "Cannot transliterate character between character sets Unable to execute query". Как это побороть - не понимаю, помогите, пожалуйста, разобраться. :clapping:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 16.3.2012, 8:09
Сообщение #12


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Оля, сразу вот такой моментик.

>>Я указываю и подтип TEXT, и кодировку блоба
+
>>Данные для очередной записи таблицы поступают ко мне в виде структуры:

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

Далее - с байтовым блобом проблем никогда не бывает. Считываешь , незабываешь зеро-терминатор на конце, подсовываешь парсеру XML

запись XML в базу: QString->std::string->БД
чтение : БД->std::string->обеспечить zt->QString

я бы так сделал :)



----------------------------
>>11. Кстати, Алексей1153, если в IBExpert открыть таблицу T_MSG, а для нее страницу Data,

у меня энто самое... subtype==binary )

CREATE TABLE T_MSG
(
    F_RECORD_NMB  BIGINT NOT NULL,
    F_MSG_TEXT    BLOB SUB_TYPE 0 SEGMENT SIZE 80 NOT NULL
);


Сообщение отредактировал Алексей1153 - 16.3.2012, 8:09
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 16.3.2012, 10:41
Сообщение #13


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


Цитата(Алексей1153)
сразу резко напрашивается использование XML , а , следовательно, UTF-8
Почему-это "следовательно" ? XML может быть и в другой кодировке. :)

15. Как раз у нас так в проекте: данные с других компов поступают на наш комп в виде XML с кодировкой windows-1251, и с нашего компа передаются в их сторону так же.
Вот только расшифровкой / кодировкой XML занимаюсь в нашем проекте не я, а другой программист. Он же и раскладывает поступившие в XML данные в разные структуры, с которыми мы работаем, а наши выходные данные для других компов он обратно кодирует в XML.

16.
Цитата(Алексей1153)
запись XML в базу: QString->std::string->БД
чтение : БД->std::string->обеспечить zt->QString

    QString myQString = "PRIVET8: ПРИВЕТ8";
    std::string myStdString = myQString.toStdString();
А дальше? Как myStdString записать в БД? Как прочитать myStdString из БД? Как обеспечить zt? Как из этого получить QString?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 16.3.2012, 11:09
Сообщение #14


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


в другой то может,но как показывает практика,UTF-8 - стандарт. Всегда и везде без проблем с ним

Ты сама только что подтвердила - с другой кодировкой - проблемы (шутю наполовину :D )

Цитата(Steklova Olga @ 16.3.2012, 13:41) *
А дальше?


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

Цитата
void QSqlQuery::bindValue ( const QString & placeholder, const QVariant & val, QSql::ParamType paramType = QSql::In )


QSqlQuery s;
      s.prepare( QString( "update TABLE set  FIELD=:marker where ... " ) );
      s.addBindValue( QVariant (myStdString.c_str()), QSql::In/*|QSql::Binary*/ );
      s.exec( );


кстати, QVariant умеет и с QString работать - попробуй сразу оттуда

возможно, понадобится флаг QSql::Binary

в общем, в любом случае -если таким образом записать из QString в двоичный блоб,а потом так же считать, то содержимое QString должно восстановиться аки птицо Феникс, независимо от кодировок

Сообщение отредактировал Алексей1153 - 16.3.2012, 11:01
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 16.3.2012, 12:13
Сообщение #15


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


17. Кодировку БД оставила WIN1251.
Опять изменила структуру таблицы T_MSG, использовала другие домены:
CREATE DOMAIN D_VARCHAR_0020 AS
VARCHAR(20) CHARACTER SET WIN1251
COLLATE PXW_CYRL;

CREATE DOMAIN D_BLOB_TEXT_0020 AS
BLOB SUB_TYPE 1 SEGMENT SIZE 20 --SUB_TYPE 1 == TEXT
CHARACTER SET WIN1251;

CREATE DOMAIN D_BLOB_BINARY_0020 AS
BLOB SUB_TYPE 0 SEGMENT SIZE 20; --SUB_TYPE 0 == BINARY

CREATE TABLE T_MSG (
    F_RECORD_NMB D_INTEGER NOT NULL,
    F_MSG_TEXT_VC D_VARCHAR_0020 NOT NULL,
    F_MSG_TEXT_B D_BLOB_TEXT_0020 NOT NULL,
    F_MSG_TEXT_BIN D_BLOB_BINARY_0020 NOT NULL
);

Использовала подготовленный запрос:
    if (!query.prepare("INSERT INTO T_MSG "
                  "(F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B, F_MSG_TEXT_BIN) "
                  "VALUES (:F_RECORD_NMB, :F_MSG_TEXT_VC, :F_MSG_TEXT_B, :F_MSG_TEXT_BIN)")) {
        qDebug() << "не удалось успешно подготовить запрос";
        return 1;
    }
    query.bindValue(":F_RECORD_NMB", 7);
    query.bindValue(":F_MSG_TEXT_VC", "PRIVET7: ПРИВЕТ7");
    query.bindValue(":F_MSG_TEXT_B", "PRIVET7: ПРИВЕТ7");

    QString myQString = "PRIVET7: ПРИВЕТ7";
    std::string myStdString = myQString.toStdString();
    query.bindValue(":F_MSG_TEXT_BIN", QVariant(myStdString.c_str()), QSql::In | QSql::Binary);

    query.exec();
    if (!query.isActive()) {
        qDebug() << "не удалось успешно выполнить запрос:"
                << query.lastError().text();
        return 2;
    }

Все равно, как и в пункте 14 (независимо от того, указать QSql::In или QSql::In | QSql::Binary), после выполнения query.exec() ВЫЛЕЗАЕТ ОШИБКА "Cannot transliterate character between character sets Unable to execute query".
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 16.3.2012, 12:41
Сообщение #16


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


. У тебя есть скайп ? Скинь в ЛС, а то так долго получается
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 16.3.2012, 14:48
Сообщение #17


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


OK
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 3.4.2012, 19:56
Сообщение #18


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Steklova Olga @ 14.3.2012, 15:59) *
Почему у меня некорректно (крокозябрами) отображается русский текст из BLOB в колонке QTableView ?
Потомучто:
Цитата(Steklova Olga @ 14.3.2012, 15:59) *
QTextCodec::setCodecForCStrings(QTextCodec::codecForName(RUSCODEC));

Не трогай кодировку "Си-строк" (CStrings) без крайней надобности.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 3.4.2012, 21:57
Сообщение #19


Участник
**

Группа: Участник
Сообщений: 198
Регистрация: 27.9.2011
Из: Санкт-Петербург
Пользователь №: 2912

Спасибо сказали: 5 раз(а)




Репутация:   4  


И за что мне такое внимание сегодня с Вашей стороны, Юрий! Прям на все мои вопросы отвечаете. Спасибо большое! :give_rose:

Цитата
Не трогай кодировку "Си-строк" (CStrings) без крайней надобности.
Извините, но я полный чайник в кодировках. Ничего не понимаю, что Вы хотите этим сказать. Уточните, пожалуйста. :)

P.S.
Если я в моем проекте из main.cpp уберу строки
#define RUSCODEC "CP1251"
QTextCodec::setCodecForCStrings(QTextCodec::codecForName(RUSCODEC));
то у меня весь русский текст на экране будет крокозябрами, а не только в BLOB,

а вот если оставить, то русский выглядит по-русски, в том числе и в поле VARCHAR,
при том, что в это поле VARCHAR я пишу тот же текст, что и в поле BLOB. Как это объяснить? :rolleyes:


Сообщение отредактировал Steklova Olga - 4.4.2012, 9:38
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 4.4.2012, 11:03
Сообщение #20


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Вобщем есть такая проблема:
По моему (и не только) разумению Qt должна сама разруливать ситуацию с кодировками, ведь есть функции типа QObject::trUtf8(). Т.е. указывается только кодировка исходника, дальнейшие действия идут сами по себе, т.к. внутри Qt всегда одна и та же кодировка.

Так же должно быть и в случае с БД, драйвер запрашивает кодировку из БД и сам всё конвертирует туда-сюда.

На практике: драйвер считает что данные из БД идут "только на английском" (т.е. кодировка Си строк) - что есть бред. Мало того, родной (от Тролтеха/Нокии) драйвер интербэйза кривой, насколько я помню для Qt версии до 4.5 невозможно задать параметры соединения (как минимум кодировку).
Была попытка исправить кучу грехов на прог.орге название темы сейчас не помню, но тогда чувак родил более-мение вменяемый драйвер.

Когда ты устанавливаешь кодировку для Си-строк, то работает одна БД. А вот представь себе, если тебе нужно работать с несколькими БД одновременно и у них разные кодировки (реальная жизнь). На данном этапе задача для стандартных драйверов Qt не решаемая.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

3 страниц V  < 1 2 3 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.11.2024, 11:28