crossplatform.ru

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

3 страниц V   1 2 3 >  
Ответить в данную темуНачать новую тему
Steklova Olga
  опции профиля:
сообщение 14.3.2012, 13:59
Сообщение #1


Участник
**

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

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




Репутация:   4  


Здравствуйте :) У меня в таблице БД есть поле BLOB для хранения текста.

Вопрос 1.
Почему у меня некорректно (крокозябрами) отображается русский текст из BLOB в колонке QTableView ?
Вопрос 2.
Как сделать, чтобы текст в колонке с BLOB не отображался весь в одну строку, а переносился ?
Вопрос 3.
Что делать с шириной колонки для поля BLOB ? Ограничивать ?

Мои предположения:
- не в той кодировке пишу данные в БД ?
- не везде, где надо, правильно указала кодировку ?
- мне необходимо создать делегат, чтобы в каждой ячейке QTableView колонки с BLOB был виджет QTextEdit ?
(Сейчас никакого делегата для этого QTableView у меня нет.)

Делаю так:
в скриптах при создании БД:
----------------------
SET SQL DIALECT 3;
CREATE DATABASE 'D:\DB1.FDB' USER 'SYSDBA' PASSWORD 'masterkey'
DEFAULT CHARACTER SET WIN1251;
EXIT;
----------------------
SET SQL DIALECT 3;
SET NAMES WIN1251;
CONNECT 'D:\DB1.FDB' USER 'SYSDBA' PASSWORD 'masterkey';
CREATE DOMAIN D_INTEGER AS
INTEGER;
CREATE DOMAIN D_BLOB_TEXT_1000 AS
BLOB SUB_TYPE 1 SEGMENT SIZE 1000 --SUB_TYPE 1 == TEXT
CHARACTER SET WIN1251;
COMMIT;
EXIT;
----------------------
SET SQL DIALECT 3;
SET NAMES WIN1251;
CONNECT 'D:\DB1.FDB' USER 'SYSDBA' PASSWORD 'masterkey';
CREATE TABLE T_MSG (
    F_RECORD_NMB D_INTEGER NOT NULL,
    F_MSG_TEXT   D_BLOB_TEXT_1000 NOT NULL
);
ALTER TABLE T_MSG ADD CONSTRAINT PK_T_MSG PRIMARY KEY (F_RECORD_NMB);
COMMIT;
EXIT;
----------------------
SET SQL DIALECT 3;
SET NAMES WIN1251;
CONNECT 'D:\DB1.FDB' USER 'SYSDBA' PASSWORD 'masterkey';
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT) VALUES (1, 'PRIVET: ПРИВЕТ');
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT) VALUES (2, 'OTVET: ОТВЕТ');
COMMIT WORK;
EXIT;
----------------------

В IBExpert при регистрации БД указываю:
- Charset = WIN1251
- оставляю не включенным (как по умолчанию и есть) флаг
Do NOT perform conversion from/to UTF8
- Font Characters Set = RUSSIAN_CHARSET
При этом в IBExpert данные поля BLOB таблицы отображаются корректно,
как и при включенном флаге (не совсем понимаю, что делает этот флаг).

в main.cpp:
#include <QtCore/QTextCodec>
#define RUSCODEC "CP1251"

int main(int argc, char *argv[])
{
    ...
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName(RUSCODEC));
}
в mainwindow_db.cpp (в главном окне):
void MainWindow_db::create_model_msg_list()
{
    //создание модели
    model_msg_list = new QSqlTableModel(this);
    model_msg_list->setEditStrategy(QSqlTableModel::OnFieldChange);
    model_msg_list->setTable("T_MSG");

    //задание заголовков столбцов
    model_msg_list->setHeaderData(0, Qt::Horizontal, "№ сообщ.");
    model_msg_list->setHeaderData(1, Qt::Horizontal, "Текст сообщ.");

    //задание модели для представления
    view_msg_list->setModel(model_msg_list);
    view_msg_list->setSelectionMode(QAbstractItemView::SingleSelection); //сколько выделять: один
    view_msg_list->setSelectionBehavior(QAbstractItemView::SelectRows); //что выделять: строки
    view_msg_list->setEditTriggers(QAbstractItemView::NoEditTriggers); //представление табл доступно только для чтения

    //установить ширину колонок
    view_msg_list->resizeColumnsToContents();

    view_msg_list->verticalHeader()->hide();
}
в mainwindow_db.h:
class MainWindow_db : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow_db(QWidget *parent = 0);
    QSqlTableModel *model_msg_list;
    ...
private:
    QTableView *view_msg_list;
    void create_model_msg_list();
    ...
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 14.3.2012, 14:30
Сообщение #2


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

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

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




Репутация:   34  


1 - полагаю, блобу абсолютно пофиг на кодировку - это поток байтов. Как вытаскиваешь данные для записи в блоб, так нужно и обратно заталкивать (к примеру, через посредника std::string - у QString есть метод для получения такого объекта. )

Возможно, нужно применить другой тип поля - VARCHAR или что там

2 - опять же, производится, скорее всего, попытка отобразить байтовый поток в виде строки. И это прекрасно удаётся :D . Выход - только ручками как-то выводить так, как нужно, разбавляя переносами строки

3 - 2

Сообщение отредактировал Алексей1153 - 14.3.2012, 14:31
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 14.3.2012, 14:44
Сообщение #3


Участник
**

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

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




Репутация:   4  


Цитата(Алексей1153)
Возможно, нужно применить другой тип поля - VARCHAR
В этой таблице у этого поля мне нужен тип BLOB с текстом, а не VARCHAR, потому что заранее совершенно неизвестно количество символов.

Цитата
Как вытаскиваешь данные для записи в блоб, так нужно и обратно заталкивать (к примеру, через посредника std::string - у QString есть метод для получения такого объекта.
не поняла

В том, что у меня сейчас сделано, насколько я понимаю, везде указана одна и та же кодировка - WIN1251.

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


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

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

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




Репутация:   34  


Оля, ты, судя по всему, используешь Огнептицу

я попробовал у себя в эксперте - сделал такую же таблицу, выполнил вставку. Штатный просмотрщик блоба говорит, что всё видно.
 Р В Р’ Р’ Р’ Р в‚¬Р В РЎВ˜Р В Р’µР Р…ьшено Р Т‘Р С• 71%
Прикрепленное изображение
889 x 539 (55.33 килобайт)


Видимо дело у тебя в кодировке текста скрипта - ты как его выполняешь ? В коде программы ?

И повторюсь - у блоба нет понятия кодировки, там тупо байты. Вот таким образом, как ты делаешь вставку, я никогда не делал (хотя это сработало - скрин). Я вставлял маркер "?", а только потом данные в виде бинарного массива. Но в моём случае было WinAPI. Как тут это провернуть - я не в курсе

Сообщение отредактировал Алексей1153 - 14.3.2012, 20:03
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 15.3.2012, 8:15
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

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




Репутация:   17  


Цитата(Алексей1153 @ 15.3.2012, 0:01) *
И повторюсь - у блоба нет понятия кодировки, там тупо байты. Вот таким образом, как ты делаешь вставку, я никогда не делал (хотя это сработало - скрин). Я вставлял маркер "?", а только потом данные в виде бинарного массива. Но в моём случае было WinAPI. Как тут это провернуть - я не в курсе

Тут ты не совсем прав.
В Firebird-е при создании блоба указывается его подтип. Ежели подтип блоба TEXT, то его кодировка так же может быть указана явно либо взята дефолтная.
Раньше, кодировки установленные для блобов игнорировались, но начиная с версии 2.1 сервер работает с блобами в этом отношении так же как и с остальными текстовыми типами.

Соответственно, при работе с текстовыми блобами в птичке нужно учитывать версию сервера.

П. С. Судя по скриншоту, ты используешь виндовый IBExpert. Насколько я в курсе, это один из самых совершенных просмотрщиков для птички, и проблемам кодировок в нём постоянно уделяется довольно много времени.
Так что не все результаты «влёгкую» полученные на нём можно просто воспроизвести на каком-либо другом продукте или в коде. :)
Например если в русском сообществе разработчиков птицы при описании какого-нибудь эффекта/бага сервера ты используешь IBE, тебе, скорее всего, настоятельно порекомендуют повторить его на штатном консольном клиенте. :)

Сообщение отредактировал Tonal - 15.3.2012, 8:34
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 15.3.2012, 9:33
Сообщение #6


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

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

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




Репутация:   34  


Tonal, возможно
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 15.3.2012, 11:33
Сообщение #7


Участник
**

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

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




Репутация:   4  


1. Использую FireBird 2.1 в Windows.
2. У меня тоже в IBExpert данные поля BLOB таблицы отображаются корректно.
3.
Цитата(Tonal)
В Firebird-е при создании блоба указывается его подтип. Ежели подтип блоба TEXT, то его кодировка так же может быть указана явно либо взята дефолтная
Я указываю и подтип TEXT, и кодировку блоба. :rolleyes:
4.
Цитата(Алексей1153)
Видимо дело у тебя в кодировке текста скрипта - ты как его выполняешь ? В коде программы ?
Для начала, я попробовала вставить в таблицу T_MSG записи с BLOB с помощью скрипта вставки данных.
В первом сообщении я привела тексты скриптов создания БД, доменов, таблицы и вставки данных.
Тексты скриптов набирала в IBExpert.
Еще есть общий скрипт, который я выполнила в IBExpert (Tools | Script Executive):
/*   SeriesOfScripts.sql   */
--создание пустой БД
  INPUT 'D:\CreateDatabase.sql';
  INPUT 'D:\CreateDomains.sql';
  INPUT 'D:\CreateTables.sql';
--заполнение таблиц для тестирования программ
  INPUT 'D:\FillTables.sql';

5. На самом деле, мне надо будет вставлять в таблицу T_MSG записи с BLOB в коде программы с помощью QSqlQuery "INSERT INTO T_MSG ..."
Данные для очередной записи таблицы поступают ко мне в виде структуры:
typedef struct {
    qint32 recNmb;
    QString msg; 
} tMsg;

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 15.3.2012, 15:13
Сообщение #8


Участник
**

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

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




Репутация:   4  


6. Для теста изменила структуру таблицы 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 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
);
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B) 
VALUES (1, 'PRIVET1: ПРИВЕТ1', 'PRIVET1: ПРИВЕТ1');
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B) 
VALUES (2, 'PRIVET2: ПРИВЕТ2', 'PRIVET2: ПРИВЕТ2');

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);

В результате в QTableView: во всех записях (с номерами 1-4) в поле F_MSG_TEXT_VC русский есть, в поле F_MSG_TEXT_B русского нет.
Посмотрела данные таблицы T_MSG в IBExpert: во всех записях (с номерами 1-4) в полях F_MSG_TEXT_VC и F_MSG_TEXT_B русский есть.

Сообщение отредактировал Steklova Olga - 15.3.2012, 15:49
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 15.3.2012, 15:58
Сообщение #9


Участник
**

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

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




Репутация:   4  


8. Если оставить все как есть, но попробовать поменять кодировку блоба:
CREATE DOMAIN D_BLOB_TEXT_0020 AS
BLOB SUB_TYPE 1 SEGMENT SIZE 20 --SUB_TYPE 1 == TEXT
CHARACTER SET UNICODE_FSS;
то результат такой же, как в пункте 7. :unsure:

9. В пункте 4., при выполнении общего скрипта в IBExpert (Tools | Script Executive) из вариантов Execute charset: (ANSI, UTF8, Ask me) выбран вариант по умолчанию (ANSI).

10. А в IBExpert при регистрации БД в каком случае надо включать флаг "Do NOT perform conversion from/to UTF8" ?

Сообщение отредактировал Steklova Olga - 15.3.2012, 17:55
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 15.3.2012, 18:51
Сообщение #10


Участник
**

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

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




Репутация:   4  


11. Кстати, Алексей1153, если в IBExpert открыть таблицу T_MSG, а для нее страницу Data,
то у вас в поле F_MSG_TEXT отображается иконка,
а у меня вместо нее - начальные символы текста блоба, а в hint'е - полный текст блоба.

И еще. Кроме вариантов просмотра блоба As Text, As Hex, As Picture, As RTF, As Web Page, которые есть у вас,
у меня еще есть варианты As XML и As Unicode Text.

Это связано с тем, что у нас разные версии IBExpert?

12. Открыла в IBExpert таблицу T_MSG. Нажала кнопку Export Data into Script. Отметила поле F_MSG_TEXT_B, чтобы его данные тоже записались в скрипт. Выбрала имя файла 1.sql. Нажала кнопку Export.
Получила два файла: 1.sql и 1.lob.
в файле 1.sql:
SET BLOBFILE 'D:\1.lob';
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B)
           VALUES (1, 'PRIVET: ПРИВЕТ', :h00000000_0000000E);
INSERT INTO T_MSG (F_RECORD_NMB, F_MSG_TEXT_VC, F_MSG_TEXT_B)
           VALUES (2, 'OTVET: ОТВЕТ', :h0000000E_0000000C);
COMMIT WORK;
в файле 1.lob:
PRIVET: ПРИВЕТOTVET: ОТВЕТ
Смотрела файл 1.lob в Notepad++. Он говорит, что файл - в кодировке ANSI. Выглядит по-русски.
":h0000000E_0000000C" означает, что данные блоба для второй записи располагаются в файле 1.lob, начиная с адреса 0000000E и занимают 0000000C байтов ?

13. Конкретно эту Qt-шную программу я не планирую переводить на другой язык (англ), поэтому unicode вроде-бы мне не нужен. Я собиралась использовать БД в WIN1251.

Эксперименты продолжаются. BLOB не сдается, вредина. Но очень хотелось бы все-таки с ним разобраться! :rolleyes:

Сообщение отредактировал Steklova Olga - 15.3.2012, 18:57
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
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


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

Группа: Участник
Сообщений: 2943
Регистрация: 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


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

Группа: Участник
Сообщений: 2943
Регистрация: 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


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

Группа: Участник
Сообщений: 2943
Регистрация: 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 не решаемая.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 5.4.2012, 20:21
Сообщение #21


Участник
**

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

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




Репутация:   4  


Litkevich Yuriy, просмотрела кучу тем на prog.org.ru и crossplatform.ru.
Не про эту ли тему на prog.org Вы говорили? :rolleyes: "Русские строки в исходниках. Windows-1251"
Ответ пока не нашла. Драйверы пока-что сама не писала.

Пока гуглила, нашла полезную для себя cсылку:
"Linuxcenter.ru » Библиотека Линуксцентра » Книги и руководства » Разработка графического интерфейса с помощью библиотеки Qt3"
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 18.4.2012, 11:59
Сообщение #22


Участник
**

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

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




Репутация:   4  


Цитата(Алексей1153 @ 16.3.2012, 11:09) *
из-под 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, спасибо Вам большое за поддержку, оказывается, все элементарно :D
1. я отказалась от использования текстового блоба, так как не разбираюсь в драйверах.

2. изменила скрипт, остановившись на использовании двоичного блоба:
CREATE DOMAIN D_BLOB_BINARY_0500 AS
BLOB SUB_TYPE 0 SEGMENT SIZE 500; --SUB_TYPE 0 == BINARY

CREATE TABLE T_MSG (
    F_RECORD_NMB D_INTEGER NOT NULL,
    F_MSG_TEXT_BIN D_BLOB_BINARY_0500 NOT NULL
);

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

4. Все эти варианты работают:
    query.bindValue(":F_MSG_TEXT_BIN", "ПРИВЕТ 1"); 

    query.bindValue(":F_MSG_TEXT_BIN", QString("ПРИВЕТ 2")); 

    QString s = "ПРИВЕТ 3";
    query.bindValue(":F_MSG_TEXT_BIN", s);

    QByteArray ba;
    ba.append("ПРИВЕТ 4");
    query.bindValue(":F_MSG_TEXT_BIN", ba);

5. А ошибки продолжали вылезать тогда, когда я только начала тестировать использование двоичного блоба, не из-за двоичного блоба, а из-за того, что в то время у меня и в таблице БД оставалось обязательное поле текстового блоба, и в подготовленном запросе вместе с указанием двоичного блоба я ПРОДОЛЖАЛА УКАЗЫВАТЬ ПОЛЕ ТЕКСТОВОГО БЛОБА, которое и вызывало ошибку. Слонов надо есть по частям! :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 18.4.2012, 12:16
Сообщение #23


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

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

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




Репутация:   34  


ещё мне что-то подсказывает, что более рационально задавать сегмент размером , равным степени двойки. К примеру, не 500, а 512
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 18.4.2012, 13:10
Сообщение #24


Участник
**

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

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




Репутация:   4  


Алексей1153, да, наверное.
В книге Хелен Борри "Firebird. Руководствоо разработчика баз данных" на стр 223 в главе 12 "BLOB и массивы" нашла следующие слова:
Цитата
"Сегменты BLOB.
Данные BLOB... хранятся в виде сегментов на одной или более страницах базы данных.
...Когда это возможно, BLOB сохраняются на той же странице, что и запись с остальными данными.
При этом большие BLOB могут занимать много страниц, а их начальные страницы могут содержать не данные, а массив указателей на страницы с содержимым BLOB."
Если страницы с содержимым BLOB хранят только данные BLOB и там нет никакой вспомогательной информации (в книге я не нашла подтверждения этого), то Вы правы.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 1.6.2025, 23:28