7

このクエリでコードを起動すると、リストされているすべてのテーブルが表示される場合もあれば、1 つしか表示されない場合もあり、常に次のエラーが発生します。

クエリ エラー: エラー: SQLITE_MISUSE: 不明なエラー

SQLITE API が不適切に使用された場合に SQLITE_MISUSE が発生することを読みました。このコードで何が問題なのか分からないので、助けていただけませんか。

編集。競合の問題を取り除くために、コードに変更を加えました。

SQLITE_MISUSE エラーのメッセージは引き続き発生しますが、テーブルが消失する問題はなくなりました。私のクエリでのレースがそうでした。

これがコードです。

var sqlite3 = require("node-sqlite3");
var fs = require('fs');

var query_count;
var init = function (response) {
    var db = new sqlite3.Database("test.db", function() {

        fs.readFile('./assets/sql/initDB.sql', function(err,data){
            if(err) {
                console.error("Could not open file: %s", err);
                return;
            }

            var query = data.toString('utf8');
            queries = query.split(";");

            db.serialize(function() {
                query_count = queries.length;
                for(var i=0; i<queries.length; i++) {
                    queries[i] = queries[i].replace("\r\n","");
                    db.run(queries[i], function(error) {
                        if(error) {
                            console.log("Query Error: "+error);
                        }

                        query_count--;

                        if( query_count <= 0 ) {
                            db.close();
                            listAllTables(response);
                        }
                    });
                }
            });
        });
    });
};

function listAllTables(response) {
    var db = new sqlite3.Database("./assets/sql/test.db", function () {
        db.all("SELECT name FROM sqlite_master WHERE type = 'table'", function (error, records) {
            for(var record in records) {
                response.write(record+": "+records[record]+"\n");
                for(var prop in records[record]) {
                    response.write("\t"+prop+": "+records[record][prop]+"\n");
                }
            }

            response.end();
            db.close();
        });
    });
}

exports.load_customers = function(response) {
    init(response);
};

クエリ ファイル initDB.sql は次のようになります。

CREATE TABLE IF NOT EXISTS TemporaryAuthTokens (
  authToken TEXT PRIMARY KEY NOT NULL UNIQUE,
  expireDate NUMERIC NOT NULL);

CREATE  TABLE IF NOT EXISTS User (
  id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE  ,
  login TEXT NOT NULL ,
  pass TEXT NOT NULL ,
  creationDate NUMERIC NOT NULL ,
  authToken TEXT NULL REFERENCES TemporaryAuthTokens(authToken)
  );
4

2 に答える 2

12

競合状態があります。最後のクエリ (コールバックが接続を閉じる) が、以前のクエリのいずれかが終了する前に終了する可能性があり、言うまでもなく、以前のクエリをホースします。最後に開始するクエリではなく、最後に終了するクエリが接続を閉じるように、コードを作り直す必要があります(たとえば、クエリの数にカウンターを設定し、各クエリが終了するとそれをデクリメントします。デクリメントするものゼロにすると接続が閉じます)。

またserialize、データベース オブジェクトで使用できるメソッドを確認することもできます。現在、初期化クエリはすべて互いに独立していますが、外部キー制約を使用し始めた場合、参照されるテーブルがまだ作成されていないと問題が発生するため、実行順序を強制する必要があります。

于 2012-08-27T09:52:31.090 に答える