Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да изпращате C++ и mysql динамични mysql заявки

Използвайте подготвен оператор, който ви позволява да параметризирате стойности, подобно на това как функциите ви позволяват да параметризирате променливи в блокове на оператори. Ако използвате 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

Създайте класове за обработка на достъпа до база данни и го обвийте в метод, а останалата част от приложението дори не трябва да знае, че се използва база данни.

Ако наистина искате да използвате стария C API по някаква причина:

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

Както виждате, Connector/C++ е по-прост. Освен това е по-малко податлив на грешки; Вероятно направих повече грешки, използвайки C API, отколкото Connector/C++.

Вижте също:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на различни механизми за съхранение на MySQL в дизайна на база данни

  2. MySQL 5.0 индекси – уникални срещу неуникални

  3. Функция MySQL LOG10() – Връщане на логаритъм на база 10 на стойност

  4. Скриптове през ssh чрез замазка на windows

  5. org.hibernate.AssertionFailure:нулев идентификатор в записа (не изтривайте сесията след възникване на изключение)