1

これら 2 つのクエリをどのように組み合わせることができますか?

2 番目のクエリでテーブルが見つからないというエラーが発生しました。これは、最初のクエリでの sqlite 呼び出しの一部に関係していると思います。

NSString *dayName = del.dayName;
int rowCount = del.tableRowNumber;

NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:@"banklist" ofType:@"sqlite3"];

if(sqlite3_open([sqLiteDb UTF8String], &_database) == SQLITE_OK)
{
    NSString *sqlStatement = [NSString stringWithFormat:@"UPDATE %@ SET recipe_name='%@' WHERE cell_id='%i'",dayName, info.name, rowCount];
    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(_database, [sqlStatement UTF8String] , -1, &compiledStatement, NULL) == SQLITE_OK)
    {
        sqlite3_bind_text( compiledStatement, 1, [sqLiteDb UTF8String], -1, SQLITE_TRANSIENT);
    }
    if(sqlite3_step(compiledStatement) != SQLITE_DONE )
    {
        NSLog( @"Save Error: %s", sqlite3_errmsg(_database) );
    }
    else
    {
        sqlite3_reset(compiledStatement);
    }

    sqlite3_finalize(compiledStatement);


    NSString *sqlStatement2 = [NSString stringWithFormat:@"UPDATE %@ SET recipe_id = (SELECT key FROM recipes WHERE name = Monday.recipe_name)",dayName];
    sqlite3_stmt *compiledStatement2;

    if(sqlite3_prepare_v2(_database, [sqlStatement2 UTF8String] , -1, &compiledStatement2, NULL) == SQLITE_OK)
    {
        sqlite3_bind_text( compiledStatement2, 1, [sqLiteDb UTF8String], -1, SQLITE_TRANSIENT);
    }
    if(sqlite3_step(compiledStatement2) != SQLITE_DONE )
    {
        NSLog( @"Save Error: %s", sqlite3_errmsg(_database) );
    }
    else
    {
        sqlite3_reset(compiledStatement2);
    }

    sqlite3_finalize(compiledStatement2);
}

sqlite3_close(_database);

ありがとう

4

2 に答える 2

1

ステートメントの次の部分に誤りがある可能性があります。

SELECT key
FROM recipes
WHERE name = Monday.recipe_name
于 2013-09-04T17:07:49.753 に答える
1

いくつかの観察:

  1. を使用してクエリにパラメータを提供したくない場合がありますstringWithFormat。レシピが「パットの悪名高いクッキー」だったら?そのアポストロフィは文字列を終了するものとして解釈され、準備関数は失敗します。SQL でプレースホルダーを使用?し、値をバインドする必要があります。SQLite ドキュメントのセクション 3を参照してください。

  2. 上記の関数を使用することをお勧めしますsqlite3_bind_textが、実際には呼び出しsqlite3_bind_textて、データベース ファイルへのパスを渡しています。それか

    • ?この値をバインドするプレースホルダーがないため、SQL を考えると意味がありません。と

    • データベースのパスを渡す理由がまったくわかりません。

    その呼び出しはおそらくうまくいかないようです。その既存のsqlite_bind_text呼び出しの戻りコードを確認すると、そうではないことに賭けSQLITE_OKます。

  3. 呼び出しが失敗した場合(これは、SQL を改良する際によくある失敗点ですsqlite3_prepare_v2)、. sqlite3_errmsg失敗したsqlite3_errmsg後にsqlite3_prepare_v2表示されるエラー メッセージは、最も有用なエラー メッセージの 1 つです (SQL の何が問題なのかを正確に教えてくれます)。sqlite3_errmsgが返らない場合sqlite3_prepare_v2は必ず調べてくださいSQLITE_OK

したがって、次のようになります。

if(sqlite3_open([sqLiteDb UTF8String], &_database) == SQLITE_OK)
{
    NSString *sqlStatement = [NSString stringWithFormat:@"UPDATE %@ SET recipe_name=? WHERE cell_id=?",dayName];
    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(_database, [sqlStatement UTF8String] , -1, &compiledStatement, NULL) != SQLITE_OK)
    {
        NSLog(@"%s: prepare failed: %s", __FUNCTION__, sqlite3_errmsg(_database));
        sqlite3_close(_database);
        return;
    }

    if (sqlite3_bind_text( compiledStatement, 1, [info.name UTF8String], -1, SQLITE_TRANSIENT) != SQLITE_OK)
    {
        NSLog(@"%s: bind_text failed: %s", __FUNCTION__, sqlite3_errmsg(_database));
        sqlite3_finalize(compiledStatement);
        sqlite3_close(_database);
        return;
    }

    if (sqlite3_bind_int( compiledStatement, 2, rowCount) != SQLITE_OK)
    {
        NSLog(@"%s: bind_int failed: %s", __FUNCTION__, sqlite3_errmsg(_database));
        sqlite3_finalize(compiledStatement);
        sqlite3_close(_database);
        return;
    }

    if (sqlite3_step(compiledStatement) != SQLITE_DONE )
    {
        NSLog(@"Save Error: %s", sqlite3_errmsg(_database) );
        sqlite3_finalize(compiledStatement);
        sqlite3_close(_database);
        return;
    }

    // you don't need this unless you're going to reuse that prepared statement, which you aren't
    //
    //else
    //{
    //    sqlite3_reset(compiledStatement);
    //}

    sqlite3_finalize(compiledStatement);

    // did you really mean to hardcode "Monday" in this SQL?

    NSString *sqlStatement2 = [NSString stringWithFormat:@"UPDATE %@ SET recipe_id = (SELECT key FROM recipes WHERE name = Monday.recipe_name)",dayName];
    sqlite3_stmt *compiledStatement2;

    if(sqlite3_prepare_v2(_database, [sqlStatement2 UTF8String] , -1, &compiledStatement2, NULL) != SQLITE_OK)
    {
        NSLog(@"%s: prepare 2 failed: %s", __FUNCTION__, sqlite3_errmsg(_database));
        sqlite3_close(_database);
        return;
    }
    if(sqlite3_step(compiledStatement2) != SQLITE_DONE )
    {
        NSLog( @"Save 2 Error: %s", sqlite3_errmsg(_database) );
    }

    // again, not needed
    //
    //else
    //{
    //    sqlite3_reset(compiledStatement);
    //}

    sqlite3_finalize(compiledStatement2);
}

sqlite3_close(_database);

正直に言うと、テーブル名を動的に指定して SQL を構築するデータ モデルに夢中になっているわけではありません。すべての日を含む単一のテーブルをdayName表示し、そのテーブルに列を作成したいと思います。しかし、あなたが持っているものはうまくいくはずですが、それは単なる珍しい構造です.

于 2013-09-04T17:31:52.153 に答える