Qt подключение к oracle
Обновлено: 06.07.2024
У меня есть qt с открытым исходным кодом 5.12 и Ubuntu 18.04. Как мне подключиться к oracle 12c через ODBC? Я старался:
Пересмотренный ответ:
Шаги по настройке и тестированию подключения ODBC к базе данных Oracle 12.2 в Qt Open Source 5.12 в Ubuntu 18.04:
1) Установите предварительные условия (если они еще не установлены).
2) Установите диспетчер драйверов ODBC (unixODBC).
3) Установите драйвер Oracle ODBC.
4) Создайте файл tnsnames.ora и добавьте к нему соединение с вашей базой данных.
5) Запустите odbc_update_ini.sh , который создает/обновляет конфигурацию unixODBC, необходимую для регистрации драйвера Oracle ODBC в unixODBC и частичной настройки источника данных Oracle ODBC.
Ожидаемое содержимое конфигурационных файлов unixODBC после запуска odbc_update_ini.sh:
/.odbc.ini в uid/gid текущего пользователя. Этот файл изначально создается как root: root. Если владелец не изменился, соединения с базой данных через драйвер ODBC могут потерпеть неудачу.
7) Завершите настройку источника данных, добавив/обновив параметры
/odbc.ini, показанные ниже.
9) Обновите .bash_profile с помощью переменных среды Oracle и укажите исходный файл.
10) Проверьте соединение с источником данных Oracle ODBC.
11) Создать программу для проверки подключения ODBC к Oracle.
Ожидаемый результат (имена таблиц могут отличаться):
Вышеупомянутые шаги были проверены на версии OS/Qt ниже:
Оригинальный ответ:
Похоже, вы пытаетесь использовать драйвер ODBC для SQL Server для подключения к Oracle, что для меня не имеет смысла.
Примечание. Вы должны использовать собственный драйвер, если он доступен, вместо драйвера ODBC. Поддержка ODBC может использоваться в качестве запасного варианта для совместимых баз данных, если нет собственного драйвера.
Информация о сборке с собственным драйвером Oracle OCI находится здесь
Вы можете скачать мгновенный клиент Oracle, содержащий драйвер OCI, отсюда. Согласно документации QT, вам понадобятся Instant Client Package - Basic "и" Instant Client Package - SDK ". Если вы все еще хотите использовать ODBC, вы можете попробовать загрузить Oracle" ODBC Package - Дополнительные библиотеки для включения приложений ODBC ". на странице мгновенной загрузки клиента. Для всех этих загрузок убедитесь, что вы получаете версию клиента, соответствующую вашей базе данных.
В Windows 7 я установил Qt Creator и теперь я пытаюсь подключиться к базе данных Oracle. Я установил oracle client и plsql / developer, и все работает отлично. В QT Creator у меня есть ошибка:
QsqlDatabase: драйвер QOCI не загружен
это QT документация не работает для меня Это понятный урок, как это сделать на разных платформах и в разных ситуациях?
Решение
Хорошо. Я нашел решение.
установите INCLUDE =% INCLUDE%; c: \ oracle \ oci \ include
установить LIB =% LIB%; c: \ oracle \ oci \ lib \ msvc
cd% QTDIR% \ src \ plugins \ sqldrivers \ oci
qmake oci.pro
NMAKE
Если вы не используете компилятор Microsoft, замените nmake на make in
линия выше.
но делать или же NMAKE не работает для меня Потому что я не установил Microsoft Visual C ++ на моей машине.
Я сделал инструкцию, как это сделать:
Сначала не забудьте установить исходники qt. Во время проверки установки источники флажок.
затем откройте QT командная строка minGW(начало -> все программы -> qt [версия] -> [версия] -> MinGW [версия] -> Qt [версия] для рабочего стола MinGW [версия]) и перейдите в исходную папку oci:
cd C: \ Qt \ Qt [версия] \ [версия] \ Src \ qtbase \ src \ plugins \ sqldrivers \ oci
- затем, как указано в документации, укажите путь и библиотеку OCI (интерфейс вызова Oracle):
set INCLUDE =% INCLUDE%; c: \ app \ user \ product [version] \ client_1 \ oci \ include
установить LIB =% LIB%; c: \ app \ user \ product [version] \ client_1 \ oci \ lib \ msvc
qmake oci.pro
mingw32-макияж
он создаст два .dll-файла для вас qsqloci.dll(выпускная версия) и qsqlocid.dll(отладочная версия)
C: \ Qt \ Qt [версия] \ [версия] \ Src \ qtbase \ Plugins \ sqldrivers
и скопируйте эти файлы в:
C: \ Qt \ Qt [версия] \ [версия] \ MinGW [версия] \ Plugins \ sqldrivers
и ты готов к работе. чтобы проверить соединение, попробуйте этот код:
Другие решения
Вы должны использовать QODBC инстей из QOCI ,
gogagubi ответ хороший, но шаг 4 не работает для меня, потому что установлен INCLUDE а также LIB не работает для mingw32-make ,
Это нужно установить INCPATH а также LIBS в oci.pro или используйте:
Добавьте следующие строки в oci.pro :
чао тутто;
вы можете подключиться к oracle db с драйвером QODBC, если он существует; (по умолчанию в окнах Qt существует) Как показано ниже:
Работа с базами данных в Qt происходит на различных уровнях:
1.Слой драйверов — Включает классы QSqlDriver, QSqlDriverCreator, QSqlDriverCreatorBase, QSqlDriverPlugin и QSqlResult. Этот слой предоставляет низкоуровневый мост между определенными базами данных и слоем SQL API.
2.Слой SQL API — Этот слой предоставляет доступ к базам данных. Соединения устанавливаются с помощью класса QSqlDatabase. Взаимодействие с базой данных осуществляется с помощью класса QSqlQuery. В дополнение к классам QSqlDatabase и QSqlQuery слой SQL API опирается на классы QSqlError, QSqlField, QSqlIndex и QsqlRecord.
3.Слой пользовательского интерфейса — Этот слой связывает данные из базы данных с дата-ориентироваными виджетами. Сюда входят такие классы, как QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel.
Соединение с базой данных
- QDB2 — IBM DB2 (версия 7.1 и выше
- QIBASE — Borland InterBase
- QMYSQL — MySQL
- QOCI — Драйвер Oracle Call Interface
- QODBC — Open Database Connectivity (ODBC) — Microsoft SQL Server и другие ODBC-совместимые базы данных
- QPSQL — PostgreSQL (версия 7.3 и выше)
- QSQLITE2 — SQLite версии 2
- QSQLITE — SQLite версии 3
- QTDS — Драйвер Sybase Adaptive Server
Соединиться с базой данных можно вот так:
- QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" );
- db.setHostName( "bigblue" );
- db.setDatabaseName( "flightdb" );
- db.setUserName( "acarlson" );
- db.setPassword( "1uTbSbAs" );
- bool ok = db.open();
Первая строка создает объект соединения, а последняя открывает его. В промежутке инициализируется некоторая информация о соединении, включая имя соединения, имя базы данных, имя узла, имя пользователя, пароль. В этом примере происходит соединение с базой данных MySQL flightdb на узле bigblue. Аргумент «QMYSQL» в addDatabase() указывает тип драйвера базы данных, чтобы использовать для соединения, а «mydb» — имя соединения.
Как только соединение установлено, можно вызвать статическую функцию QSqlDatabase::database() из любого места программы с указанием имени соединения, чтобы получить указатель на это соединение. Если не передать имя соединения, она вернет соединение по умолчанию.
Если open() потерпит неудачу, он вернет false. В этом случае, можно получить информацию об ошибке, вызвав QSqlDatabase::lastError().
Для удаления соединения с базой данных, надо сначала закрыть базу данных с помощью QSqlDatabase::close(), а затем, удалить соединение с помощью статического метода QSqlDatabase::removeDatabase().
Выполнение инструкций SQL
Класс QSqlQuery обеспечивает интерфейс для выполнения SQL запросов и навигации по результирующей выборке.
Для выполнения SQL запросов, просто создают объект QSqlQuery и вызывают QSqlQuery::exec(). Например, вот так:
- QSqlQuery query;
- query.exec( "SELECT name, salary FROM employee WHERE salary > 50000" );
Конструктор QSqlQuery принимает необязательный аргумент QSqlDatabase, который уточняет, какое соединение с базой данных используется. Если его не указать, то используется соединение по умолчанию.
Если возникает ошибка, exec() возвращает false. Доступ к ошибке можно получить с помощью QSqlQuery::lastError().
QSqlQuery предоставляет единовременный доступ к результирующей выборке одного запроса. После вызова exec(), внутренний указатель QSqlQuery указывает на позицию перед первой записью. Если вызвать метод QSqlQuery::next() один раз, то он переместит указатель к первой записи. После этого необходимо повторять вызов next(), чтобы получать доступ к другим записям, до тех пор пока он не вернет false. Вот типичный цикл, перебирающий все записи по порядку:
QSqlQuery может выполнять не только SELECT, но также и любые другие запросы. Следующий пример вставляет запись в таблицу, используя INSERT:
- QSqlQuery query;
- query.exec( "INSERT INTO employee (id, name, salary) "
- "VALUES (1001, 'Thad Beaumont', 65000)" );
Если надо одновременно вставить множество записей, то зачастую эффективней отделить запрос от реально вставляемых значений. Это можно сделать с помощью вставки значений через параметры. Qt поддерживает два синтаксиса вставки значений: поименованые параметры и позиционные параметры. В следующем примере показана вставка с помощью поименованного параметра:
- QSqlQuery query;
- query.prepare( "INSERT INTO employee (id, name, salary) "
- "VALUES (:id, :name, :salary)" );
- query.bindValue( ":id" , 1001);
- query.bindValue( ":name" , "Thad Beaumont" );
- query.bindValue( ":salary" , 65000);
- query.exec();
В этом примере показана вставка с помощью позиционного параметра:
- QSqlQuery query;
- query.prepare( "INSERT INTO employee (id, name, salary) "
- "VALUES (?, ?, ?)" );
- query.addBindValue(1001);
- query.addBindValue( "Thad Beaumont" );
- query.addBindValue(65000);
- query.exec();
При вставке множества записей требуется вызвать QSqlQuery::prepare() только однажды. Далее можно вызвать bindValue() или addBindValue() с последующим вызовом exec() столько раз, сколько потребуется.
Отображение данных в таблице-представлении
Классы QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel могут использоваться в качестве источников данных для классов представлений Qt, таких как QListView, QTableView и QTreeView. На практике наиболее часто используется QTableView в связи с тем, что результирующая SQL выборка, по существу, представляет собой двумерную структуру данных.
В следующем примере создается представление основанное на модели данных SQL:
- QSqlTableModel model;
- model.setTable( "employee" );
- QTableView *view = new QTableView;
- view->setModel(&model);
- view->show();
Если модель является моделью для чтения-записи (например, QSqlTableModel), то представление позволяет редактировать поля. Это можно отключить с помощью следующего кода
- view->setEditTriggers(QAbstractItemView::NoEditTriggers);
Можно использовать одну и ту-же модель в качестве источника данных для нескольких представлений. Если пользователь изменяет данные модели с помощью одного из представлений, другие представления немедленно отобразят изменения.
Классы-представления для обозначения колонок наверху отображают заголовки. Для изменения текста заголовка, используется функция setHeaderData() модели. Например:
- model->setHeaderData(0, Qt::Horizontal, QObject::tr( "ID" ));
- model->setHeaderData(1, Qt::Horizontal, QObject::tr( "Name" ));
- model->setHeaderData(2, Qt::Horizontal, QObject::tr( "City" ));
- model->setHeaderData(3, Qt::Horizontal, QObject::tr( "Country" ));
Заключение
В данной статье изложены базовые принципы работы с базами данных в Qt. Однако кроме указанных здесь возможностей еще много интересного, например, транзакции, работа с внешними ключами или создание дата-ориентированых форм. К сожалению эти темы достаточно обширны для одной статьи.
Эта заметка вкратце познакомит вас с основами использования модулей Qt для работы с реляционными базами данных. Предполагается, что знание SQL у вас уже имеется, хотя и не является столь критичным для понимания представленных примеров.
Рассматриваются базовые операции, необходимые для начала работы:
- Открытие базы данных;
- Выполнение запросов;
- Выборка записей.
Реклама
Подключение модуля sql к Qt-проекту
Для того, чтобы встроенные в Qt возможности для работы с SQL заработали, необходимо добавить в pro -файл следующую инструкцию:
Однако учитывайте, что драйвера различных баз данных устанавливаются в виде плагинов и могут отсутствовать в вашем дистрибутиве Qt. Особенно актуальной это проблема является под Windows в связи с лицензионными ограничениями на распространение бинарных пакетов. О том, как собрать нужный плагин, мы поговорим в другой раз.
Реклама
Подключение к базе данных QSQLITE
Для простоты воспользуемся драйвером QSQLITE (предназначен для работы с SQLite ), поскольку он предустановлен во всех известных мне дистрибутивах Qt. К тому же, вам не потребуется устанавливать отдельную систему управлениями базами данных.
Рассмотрим соответствующий код подключения:
Если все прошло нормально, то в результате работы этого кода у вас появится пустой файл test в рабочем каталоге приложения. Так же обратите внимание на следующие функции-члены класса QSqlDatabase , которые потребуются вам, когда вы решите воспользоваться внешним сервером баз данных:
- isValid();
- setHostName();
- setPort();
- setDatabaseName();
- setUserName();
- setPassword();
Выполнение запросов с помощью QSqlQuery
Создадим в открытой базе данных новую таблицу с помощью QSqlQuery :
Аналогичным образом с помощью функции-члена exec() можно выполнять любые запросы к базе данных. Однако имеется одна тонкость.
Вставка записей в базу данных
Если запрос использует внешние данные, то в целях безопасности не вставляйте их напрямую, а используйте комбинацию prepare() и bindValue() :
Выборка записей из базы данных
Теперь рассмотрим способ получения записей из базы данных:
Заключение
Подводя итоги приведу полный листинг рассмотренного примера (обратите внимание на его завершение, дополненное кодом удаления таблицы и закрытия соединения с базой данных):
Модуль SQL, в библиотеке Qt, предоставляет независимый от типа платформы и базы данных интерфейс, для доступа к базам данных SQL, и набор классов, обеспечивающих взаимодействие пользовательского интерфейса с базами данных.
Глава начинается с демонстрационного примера, который показывает, как установить соединение с базой данных и как выполнить произвольный SQL-код. Во втором и третьем разделах мы подробнее остановимся на том, как предоставить пользователю возможность просматривать и изменять наборы данных, используя QDataTable -- для просмотра данных в табличном виде, и QSqlForm -- в виде формы.
Прежде чем выполнить запрос к базе данных, для начала необходимо установить с ней соединение. Как правило, установление соединения с базой данных выполняется в виде отдельной функции, которую приложение вызывает на запуске, например:
Первым делом, вызовом QSqlDatabase::addDatabase(), создается экземпляр класса QSqlDatabase. Аргумент функции определяет драйвер базы данных, используемый для доступа к ней. В данном случае -- это драйвер Oracle. Коммерческая версия Qt включает в себя следующий набор драйверов: QODBC3 (ODBC), QOCI8 (Oracle), QTDS7 (Sybase Adaptive Server), QPSQL7 (PostgreSQL), QMYSQL3 (MySQL), and QDB2 (IBM DB2). В некоммерческие версии Qt входит только часть этого набора. [1]
Обычно функция, подобная createConnection() вызывается из функции main():
После установления соединения, посредством QSqlQuery, можно выполнять SQL-запросы к базе данных. Например, следующий код выполняет SQL-предложение -- SELECT: После вызова функции exec(), можно просматривать полученный набор данных: Первый вызов next() позиционирует QSqlQuery на первую запись в наборе данных. Последующие вызовы next() передвигают указатель на следующую запись и так до тех пор, пока не будет достигнут конец набора. В этой точке next() вернет false.
Функция value() возвращает значение поля в виде QVariant. Поля нумеруются, начиная с 0, в порядке их следования в предложении SELECT. Класс QVariant может хранить огромное количество типов языка C++ и Qt, в том числе int и QString. Различные типы данных, которые могут храниться в базе данных переводятся в соответствующие типы C++ и Qt, и сохраняются в виде QVariant. Например, VARCHAR представляется в виде QString, а DATETIME -- как QDateTime.
Класс QSqlQuery предоставляет целый набор функций для навигации по набору данных: first(), last(), prev(), seek() и at(). Они очень удобны в использовании, но на некоторых базах данных могут оказаться довольно медлительными и ресурсоемкими. С целью оптимизациии, при работе с большими наборами данных, можно вызвать QSqlQuery::setForwardOnly(true), перед exec(), а затем выполнять просмотр набора данных с помощью next(), правда в этом случае мы получаем, так называемые, однонаправленные наборы данных, т.е. такие наборы, навигация по которым может осуществляться только вперед, с помощью next().
Чуть выше говорилось о том, что SQL-запрос передается как аргумент функции exec(), но текст запроса может передаваться напрямую, конструктору QSqlQuery:
В случае необходимости вставить в запрос значения переменных или когда нежелательно, или невозможно перевести аргументы предложения INSERT в строковый вид, можно построить параметризованный запрос , с помощью функции prepare(). Текст параметризованного запроса, вместо реальных значений содержит параметры, которые заполняются фактическими значениями после создания запроса. Qt поддерживает Oracle-подобный и ODBC-подобный стили именования параметров для всех типов баз данных. В примере ниже показано использование Oracle-подобного стиля именования:
Теперь тот же самый пример, но в стиле ODBC: После создания запроса, вызовом prepare(), параметры запроса заполняются фактическими значениями, с помощью функции bindValue() или addBindValue(), после чего запрос исполняется вызовом exec(). Параметризованные запросы можно выполнять в цикле. Перед началом цикла создается запрос, а в теле цикла производится заполнение параметров новыми значениями и исполнение запроса.
Параметризованные запросы очень часто используются в тех случаях, когда в базу данных нужно записать двоичные данные или строки, которые содержат символы из наборов, не принадлежащих диапазону ASCII или Latin-1. Для баз данных, которые поддерживают Unicode, Qt использует эту кодировку символов, в других случаях выполняется преобразование строк в соответствующую кодировку.
Qt поддерживает механизм транзакций для баз данных, в которых он присутствует. Для запуска транзакции вызывается метод объекта QSqlDatabase -- transaction(). Для завершения транзакции вызывается либо функция commit(), либо rollback(). Например, выполним поиск по внешнему ключу и вставим запись в таблицу в рамках транзакции:
Функция QSqlDatabase::database() возвращает указатель на объект QSqlDatabase, который был создан в createConnection(). Если транзакция не может быть запущена, QSqlDatabase::transaction() возвращает false.
Некоторые базы данных не поддерживают механизм транзакций. В этом случае, функции transaction(), commit() и rollback() не выполняют никаких действий. Наличие поддержки механизма транзакций, той или иной базой данных, можно проверить с помощью метода hasFeature(), объекта QSqlDriver, ассоциированного с базой данных:
В примерах выше рассматривались случаи с единственным подключением к базе данных. Однако ничто не мешает нам создать и второе, и третье и т.д. соединения. В этом случае необходимо просто передать имя соединения, вторым аргументом в функцию addDatabase(): Чтобы потом получить указатель на объект QSqlDatabase, достаточно просто передать имя соединения в функцию QSqlDatabase::database(): Для исполнения запросов через эти соединения, необходимо передать объект QSqlDatabase конструктору QSqlQuery: Каждое соединение с базой данных может поддерживать только одну активную транзакцию, поэтому множественные подключения могут оказаться полезными в том случае, когда необходимо одновременно запустить несколько транзакций. При использовании нескольких соединений, в приложении по прежнему имеется одно неименованное соединение, которое используется по-умолчанию объектами QSqlQuery, если им явно не указать с каким соединением они должны работать.
В дополнение к QSqlQuery, Qt предоставляет класс QSqlCursor, производный от QSqlQuery. Этот класс расширяет функциональность предка большим числом дополнительных методов, которые позволяют отказаться от написания SQL-запросов для наиболее употребимых SQL-операций, таких как: SELECT, INSERT, UPDATE и DELETE. Кроме того QSqlCursor выступает в роли посредника между QDataTable и базой данных. Далее, в этом разделе мы будем говорить о QSqlCursor, а в следующем разделе покажем, как можно использовать QDataTable, для представления наборов данных в табличной форме.
Следующий пример демонстрирует выполнение SQL-запроса -- SELECT:
Примечания
Читайте также: