SQL 문 실행하기
QSqlQuery 클래스는 SQL 문을 실행하고 쿼리의 결과 집합을 탐색하기 위한 인터페이스를 제공합니다.
다음 섹션에서 설명하는 QSqlQueryModel 및 QSqlTableModel 클래스는 데이터베이스에 액세스하기 위한 더 높은 수준의 인터페이스를 제공합니다. SQL에 익숙하지 않다면 다음 섹션(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
이 반환됩니다. 다음은 모든 레코드를 순서대로 반복하는 일반적인 루프입니다:
while (query.next()) {} QString name = query.value(0).toString(); int salary = query.value(1).toInt(); qDebug() << name << salary; }
QSqlQuery::value() 함수는 현재 레코드에 있는 필드의 값을 반환합니다. 필드는 0 기반 인덱스로 지정됩니다. QSqlQuery::value() 함수는 int
, QString, QByteArray 과 같은 다양한 C++ 및 Qt Core 데이터 유형을 담을 수 있는 QVariant 형을 반환합니다. 다양한 데이터베이스 유형은 가장 가까운 Qt에 해당하는 유형으로 자동 매핑됩니다. 코드 스니펫에서는 QVariant::toString() 및 QVariant::toInt()을 호출하여 변형을 QString 및 int
로 변환합니다.
Qt 지원 데이터베이스와 함께 사용하기에 권장되는 유형에 대한 개요는 이 표를 참조하세요.
QSqlQuery::next(), QSqlQuery::previous(), QSqlQuery::first(), QSqlQuery::last() 및 QSqlQuery::seek()를 사용하여 데이터 집합 내에서 탐색할 수 있습니다. 현재 행 인덱스는 QSqlQuery::at()로 반환되며, 이를 지원하는 데이터베이스의 경우 결과 집합의 총 행 수는 QSqlQuery::size()로 사용할 수 있습니다.
데이터베이스 드라이버가 특정 기능을 지원하는지 확인하려면 QSqlDriver::hasFeature()를 사용합니다. 다음 예에서는 QSqlQuery::size()를 호출하여 해당 기능을 지원하는 기본 데이터베이스의 결과 집합 크기를 확인하고, 그렇지 않은 경우 마지막 레코드로 이동하여 쿼리의 위치를 사용하여 레코드 수를 알려줍니다.
QSqlQuery query; int numRows; query.exec("SELECT name, salary FROM employee WHERE salary > 50000"); QSqlDatabase defaultDB = QSqlDatabase::database(); if (defaultDB.driver()->hasFeature(QSqlDriver::QuerySize)) { numRows = query.size(); } else { // this can be very slow query.last(); numRows = query.at() + 1; }
결과 집합 내에서 탐색하고 다음() 및 seek()를 앞으로 탐색하는 데만 사용하는 경우 실행()을 호출하기 전에 QSqlQuery::setForwardOnly(true)를 호출할 수 있습니다. 이는 대규모 결과 집합에서 작업할 때 쿼리 속도를 크게 높일 수 있는 손쉬운 최적화 방법입니다.
레코드 삽입, 업데이트 및 삭제하기
QSqlQuery 는 SELECT
뿐만 아니라 임의의 SQL 문을 실행할 수 있습니다. 다음 예는 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();
두 구문 모두 Qt에서 제공하는 모든 데이터베이스 드라이버에서 작동합니다. 데이터베이스가 해당 구문을 기본적으로 지원하는 경우 Qt는 단순히 쿼리를 DBMS로 전달하고, 그렇지 않은 경우 Qt는 쿼리를 전처리하여 플레이스홀더 구문을 시뮬레이션합니다. DBMS에서 실행되는 실제 쿼리는 QSqlQuery::executedQuery()로 사용할 수 있습니다.
여러 레코드를 삽입할 때는 QSqlQuery::prepare()를 한 번만 호출하면 됩니다. 그런 다음 bindValue() 또는 addBindValue() 다음에 exec()를 필요한 횟수만큼 호출하면 됩니다.
성능 외에도 플레이스홀더의 장점 중 하나는 특수문자 이스케이프에 대한 걱정 없이 임의의 값을 쉽게 지정할 수 있다는 점입니다.
레코드를 업데이트하는 것은 테이블에 레코드를 삽입하는 것과 비슷합니다:
QSqlQuery query; query.exec("UPDATE employee SET salary = 70000 WHERE id = 1003");
이름 바인딩이나 위치 바인딩을 사용하여 매개변수를 실제 값에 연결할 수도 있습니다.
마지막으로 DELETE
문의 예시를 살펴보겠습니다:
QSqlQuery query; query.exec("DELETE FROM employee WHERE id = 1007");
트랜잭션
기본 데이터베이스 엔진이 트랜잭션을 지원하는 경우 QSqlDriver::hasFeature(QSqlDriver::Transactions)는 참을 반환합니다. QSqlDatabase::transaction ()를 사용하여 트랜잭션을 시작한 다음 트랜잭션 컨텍스트 내에서 실행하려는 SQL 명령을 입력한 다음 QSqlDatabase::commit() 또는 QSqlDatabase::rollback()를 입력할 수 있습니다. 트랜잭션을 사용할 때는 쿼리를 만들기 전에 트랜잭션을 시작해야 합니다.
예시:
QSqlDatabase::database().transaction(); QSqlQuery query; query.exec("SELECT id FROM employee WHERE name = 'Torild Halvorsen'"); if (query.next()) { int employeeId = query.value(0).toInt(); query.exec("INSERT INTO project (id, name, ownerid) " "VALUES (201, 'Manhattan Project', " + QString::number(employeeId) + ')'); } QSqlDatabase::database().commit();
트랜잭션은 복잡한 작업이 원자적인지 확인하거나(예: 외래 키 조회 및 레코드 생성), 복잡한 변경을 중간에 취소하는 수단을 제공하는 데 사용할 수 있습니다.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.