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

  1. затем, как указано в документации, укажите путь и библиотеку 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.

Соединение с базой данных

  1. QDB2 — IBM DB2 (версия 7.1 и выше
  2. QIBASE — Borland InterBase
  3. QMYSQL — MySQL
  4. QOCI — Драйвер Oracle Call Interface
  5. QODBC — Open Database Connectivity (ODBC) — Microsoft SQL Server и другие ODBC-совместимые базы данных
  6. QPSQL — PostgreSQL (версия 7.3 и выше)
  7. QSQLITE2 — SQLite версии 2
  8. QSQLITE — SQLite версии 3
  9. QTDS — Драйвер Sybase Adaptive Server

Соединиться с базой данных можно вот так:

  1. QSqlDatabase db = QsqlDatabase::addDatabase( "QMYSQL" , "mydb" );
  2. db.setHostName( "bigblue" );
  3. db.setDatabaseName( "flightdb" );
  4. db.setUserName( "acarlson" );
  5. db.setPassword( "1uTbSbAs" );
  6. 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(). Например, вот так:
  1. QSqlQuery query;
  2. 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:
  1. QSqlQuery query;
  2. query.exec( "INSERT INTO employee (id, name, salary) "
  3. "VALUES (1001, 'Thad Beaumont', 65000)" );

Если надо одновременно вставить множество записей, то зачастую эффективней отделить запрос от реально вставляемых значений. Это можно сделать с помощью вставки значений через параметры. Qt поддерживает два синтаксиса вставки значений: поименованые параметры и позиционные параметры. В следующем примере показана вставка с помощью поименованного параметра:
  1. QSqlQuery query;
  2. query.prepare( "INSERT INTO employee (id, name, salary) "
  3. "VALUES (:id, :name, :salary)" );
  4. query.bindValue( ":id" , 1001);
  5. query.bindValue( ":name" , "Thad Beaumont" );
  6. query.bindValue( ":salary" , 65000);
  7. query.exec();

В этом примере показана вставка с помощью позиционного параметра:
  1. QSqlQuery query;
  2. query.prepare( "INSERT INTO employee (id, name, salary) "
  3. "VALUES (?, ?, ?)" );
  4. query.addBindValue(1001);
  5. query.addBindValue( "Thad Beaumont" );
  6. query.addBindValue(65000);
  7. query.exec();

При вставке множества записей требуется вызвать QSqlQuery::prepare() только однажды. Далее можно вызвать bindValue() или addBindValue() с последующим вызовом exec() столько раз, сколько потребуется.

Отображение данных в таблице-представлении


Классы QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel могут использоваться в качестве источников данных для классов представлений Qt, таких как QListView, QTableView и QTreeView. На практике наиболее часто используется QTableView в связи с тем, что результирующая SQL выборка, по существу, представляет собой двумерную структуру данных.
В следующем примере создается представление основанное на модели данных SQL:
  1. QSqlTableModel model;
  2. model.setTable( "employee" );
  3. QTableView *view = new QTableView;
  4. view->setModel(&model);
  5. view->show();

Если модель является моделью для чтения-записи (например, QSqlTableModel), то представление позволяет редактировать поля. Это можно отключить с помощью следующего кода
  1. view->setEditTriggers(QAbstractItemView::NoEditTriggers);

Можно использовать одну и ту-же модель в качестве источника данных для нескольких представлений. Если пользователь изменяет данные модели с помощью одного из представлений, другие представления немедленно отобразят изменения.
Классы-представления для обозначения колонок наверху отображают заголовки. Для изменения текста заголовка, используется функция setHeaderData() модели. Например:
  1. model->setHeaderData(0, Qt::Horizontal, QObject::tr( "ID" ));
  2. model->setHeaderData(1, Qt::Horizontal, QObject::tr( "Name" ));
  3. model->setHeaderData(2, Qt::Horizontal, QObject::tr( "City" ));
  4. 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:

Примечания

Читайте также: