Sử dụng một câu lệnh đã chuẩn bị sẵn, cho phép bạn tham số hóa các giá trị, tương tự như cách các hàm cho phép bạn tham số hóa các biến trong khối câu lệnh. Nếu sử dụng MySQL Connector / C ++ :
// use std::unique_ptr, boost::shared_ptr, or whatever is most appropriate for RAII
// Connector/C++ requires boost, so
std::unique_ptr<sql::Connection> db;
std::unique_ptr<sql::PreparedStatement> getPassword
std::unique_ptr<sql::ResultSet> result;
std::string name = "Nikolai Gogol";
std::string password;
...
getPassword = db->prepareStatement("SELECT pass FROM users WHERE name=? LIMIT 1");
getPassword->setString(1, name);
result = getPassword->execute();
if (result->first()) {
password = result->getString("pass");
} else {
// no result
...
}
// smart pointers will handle deleting the sql::* instances
Tạo các lớp để xử lý quyền truy cập cơ sở dữ liệu và gói nó trong một phương thức và phần còn lại của ứng dụng thậm chí không cần biết rằng cơ sở dữ liệu đang được sử dụng.
Nếu bạn thực sự muốn sử dụng API C cũ vì một số lý do:
MYSQL *mysql;
...
const my_bool yes=1, no=0;
const char* getPassStmt = "SELECT password FROM users WHERE username=? LIMIT 1";
MYSQL_STMT *getPassword;
MYSQL_BIND getPassParams;
MYSQL_BIND result;
std::string name = "Nikolai Gogol";
std::string password;
if (! (getPassword = mysql_stmt_init(mysql))) {
// error: couldn't allocate space for statement
...
}
if (mysql_stmt_prepare(getPassword, getPassStmt, strlen(getPassStmt))) {
/* error preparing statement; handle error and
return early or throw an exception. RAII would make
this easier.
*/
...
} else {
unsigned long nameLength = name.size();
memset(&getPassParams, 0, sizeof(getPassParams));
getPassParams.buffer_type = MYSQL_TYPE_STRING;
getPassParams.buffer = (char*) name.c_str();
getPassParams.length = &nameLength;
if (mysql_stmt_bind_param(getPassword, &getPassParams)) {
/* error binding param */
...
} else if (mysql_stmt_execute(getPassword)) {
/* error executing query */
...
} else {
// for mysql_stmt_num_rows()
mysql_stmt_store_result(getPassword);
if (mysql_stmt_num_rows(getPassword)) {
unsigned long passwordLength=0;
memset(&result, 0, sizeof(result));
result.length = &passwordLength;
mysql_stmt_bind_result(getPassword, &result);
mysql_stmt_fetch(getPassword);
if (passwordLength > 0) {
result.buffer = new char[passwordLength+1];
memset(result.buffer, 0, passwordLength+1);
result.buffer_length = passwordLength+1;
if (mysql_stmt_fetch_column(getPassword, &result, 0, 0)) {
...
} else {
password = static_cast<const char*>(result.buffer);
}
}
} else {
// no result
cerr << "No user '" << name << "' found." << endl;
}
}
mysql_stmt_free_result(getPassword);
}
mysql_stmt_close(getPassword);
mysql_close(mysql);
Như bạn thấy, Connector / C ++ đơn giản hơn. Nó cũng ít bị lỗi hơn; Có lẽ tôi đã mắc nhiều lỗi khi sử dụng API C hơn là Trình kết nối / C ++.
Xem thêm:
- Phát triển ứng dụng cơ sở dữ liệu bằng MySQL Connector / C ++
- Trình kết nối C ++ trong wiki MySQL Forge