2

すべての項目を SQLite データベースに格納したいということで、char 配列のリストを持っています。

ここで、sqlite3 Insert item through Passing parameter が完了しました。このデータベースを動的に使用したいだけです。私は C++ 開発が初めてです。

#include <iostream>
using namespace std;
#include "sqlite3.h"
#include<string.h>
#define STRING_MAX 32

typedef struct metadata_t {
    char userid[256];
    char firstname[256];
    char lastname[256];
    char username[256];
    char password[256];
    char email[256];
    char userphone[256];
    char time[256];
} metadata_t;

void insertdata1(metadata_t * data);

int main(int argc, const char *argv[])
{

    struct metadata_t *data;
    cin >> data->userid;
    cin >> data->firstname;
    cin >> data->lastname;
    cin >> data->username;
    cin >> data->password;
    cin >> data->email;
    cin >> data->userphone;
    cin >> data->time;

    insertdata1(data);

}

void insertdata1(metadata_t * data)
{
    sqlite3 *db;
    sqlite3_open("test1.db", &db);

    string createQuery =
        "CREATE TABLE IF NOT EXISTS items (userid INTEGER PRIMARY KEY, firstname TEXT,lastname TEXT,username TEXT,password TEXT,email text,userphone INTEGER, "
        "time TEXT NOT NULL DEFAULT (NOW()));";
    sqlite3_stmt *createStmt;
    cout << "Creating Table Statement" << endl;
    sqlite3_prepare(db, createQuery.c_str(), createQuery.size(),
            &createStmt, NULL);
    cout << "Stepping Table Statement" << endl;
    if (sqlite3_step(createStmt) != SQLITE_DONE)
        cout << "Didn't Create Table!" << endl;

    char *a = "(";
    char *d = ")";
    char *b = "'";
    char *c = ",";
    char str1[1000];
    char *str2 = "";
    char *g = ";";
    strcpy(str1,
           "INSERT INTO items (userid,firstname,lastname,username,password,email,userphone,time)VALUES");

    strcat(str1, a);

    strcat(str1, b);
    strcat(str1, data->userid);
    strcat(str1, b);
    strcat(str1, c);
    strcat(str1, b);
    strcat(str1, data->firstname);
    strcat(str1, b);
    strcat(str1, c);
    strcat(str1, b);
    strcat(str1, data->lastname);
    strcat(str1, b);
    strcat(str1, c);
    strcat(str1, b);
    strcat(str1, data->username);
    strcat(str1, b);
    strcat(str1, c);
    strcat(str1, b);
    strcat(str1, data->password);
    strcat(str1, b);
    strcat(str1, c);
    strcat(str1, b);
    strcat(str1, data->email);
    strcat(str1, b);
    strcat(str1, c);
    strcat(str1, b);
    strcat(str1, data->userphone);
    strcat(str1, b);
    strcat(str1, c);
    strcat(str1, b);
    strcat(str1, data->time);
    strcat(str1, b);
    strcat(str1, d);
    strcat(str1, g);

    std::string insertQuery = str1; // WORKS!
    sqlite3_stmt *insertStmt;
    cout << "Creating Insert Statement" << endl;
    sqlite3_prepare(db, insertQuery.c_str(), insertQuery.size(),
            &insertStmt, NULL);
    cout << "Stepping Insert Statement" << endl;
    if (sqlite3_step(insertStmt) != SQLITE_DONE)
        cout << "Didn't Insert Item!" << endl;

}
4

1 に答える 1

1

バインド変数を使用することをお勧めします。バインド変数を使用すると、コードがよりクリーンになり、入力エラーや SQL インジェクションからも保護されます。

害のない良い習慣もあります。

  • 関数を呼び出すたびに戻り値をチェックし、エラーの場合は(= ) またはログ ファイルに出力をsqlite3_*書き込みます。sqlite3_errmsg()stderrcerr

  • sqlite3_finalize()使用されなくなったすべての準備済みステートメントを呼び出して、完了後のクリーンアップを行います。

これらの慣行に従わないと、後で他の誰かがあなたのコードを使用またはデバッグするときに、カルマが損なわれます。

だから、ここに提案されていますinsertdata1()(私は、それが今よりきれいで読みやすいことを願っています):

// some basic error handling
void exit_with_sqlite_error(sqlite3 *db, const char* file, int line)
{
cerr << "Error: " << sqlite3_errmsg(db) << " at " << file << ":" << line << endl;
exit(1);
}

// helps to get exact location of an error 
#define EXIT_WITH_SQLITE_ERR(db) \
exit_with_sqlite_error(db, __FILE__, __LINE__)

void insertdata1(metadata_t *data)
{
sqlite3 *db;
sqlite3_open("test1.db", &db);

string createQuery = 
    "CREATE TABLE IF NOT EXISTS items ("
    "userid INTEGER PRIMARY KEY,'
    "firstname TEXT,"
    "lastname TEXT,"
    "username TEXT,"
    "password TEXT,'
    "email TEXT,"
    "userphone INTEGER,"
    "time TEXT NOT NULL DEFAULT (NOW()));";

cout << "Creating Table Statement" << endl;
int rc = sqlite3_exec(db, createQuery.c_str(), NULL, NULL, NULL);
if (rc != SQLITE_OK) 
    EXIT_WITH_SQLITE_ERR(db);

sqlite3_stmt *insertStmt = NULL;
rc = sqlite3_prepare_v2(db, 
    "INSERT INTO items "
    "(userid,firstname,lastname,username,password,email,userphone,time)"
    "VALUES"
    "(:userid,:firstname,:lastname,:username,:password,:email,:userphone,:time);",
    -1, &insertStmt, NULL);
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);

rc = sqlite3_bind_int(insertStmt, 1, atoi(data->userid));
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);
rc = sqlite3_bind_text(insertStmt, 2, data->firstname, -1, SQLITE_STATIC);
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);
rc = sqlite3_bind_text(insertStmt, 3, data->lastname, -1, SQLITE_STATIC);
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);
rc = sqlite3_bind_text(insertStmt, 4, data->username, -1, SQLITE_STATIC);
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);
rc = sqlite3_bind_text(insertStmt, 5, data->password, -1, SQLITE_STATIC);
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);
rc = sqlite3_bind_text(insertStmt, 6, data->email, -1, SQLITE_STATIC);
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);
rc = sqlite3_bind_int(insertStmt, 7, atoi(data->userphone));
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);
rc = sqlite3_bind_text(insertStmt, 8, data->time, -1, SQLITE_STATIC);
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);

rc = sqlite3_step(insertStmt);
if (rc != SQLITE_DONE && rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);

sqlite3_finalize(insertStmt);

// call to sqlite3_close() helps to find resource leaks, because it fails
// if you have obvious leaks, such as prepared statements not finalized
rc = sqlite3_close(db);
if (rc != SQLITE_OK) EXIT_WITH_SQLITE_ERR(db);
}
于 2012-07-02T11:40:06.447 に答える