7

I need to insert 10 rows to a sqlite3 table, and once the insertions are done, pass the 10 id's of the new rows to a callback function in an array.

My problem is that I can't figure out how to make a prepared statement perform multiple inserts at once. I found this post on how to do this with mySQL.

Bulk Inserts in mySQL

But this doesn't work with sqlite. My code is below:

params = [[1,2],[3,4],[5,6],[7,8]]

stmt = db.prepare("INSERT INTO test (num1, num2) VALUES (?)");
stmt.all([params], function(err, res) {
    if(err) {
        console.log(err);
        return;
    } else {
        createdIDs = []
        for (i in result) {
            createdIDs.push(result[i].id);
        }
        nextFunction(createdIDs);
    }
});

Which gives the following error:

Error: SQLITE_ERROR: 1 values for 2 columns
at Error (native)

The table's schema is like this:

db.run('CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, num1 INTEGER NOT NULL, num2 INTEGER NOT NULL)')

Edit: Using Alvaro's solution, I now get this error message:

{ [Error: SQLITE_CONSTRAINT: NOT NULL constraint failed: test.num1] errno: 19, code: 'SQLITE_CONSTRAINT' }
6
  • are you sure you did just like the answer? Commented Jul 15, 2016 at 3:38
  • @AlvaroJoao Yes, the code should be just like that other answer. The difference is that I'm using sqlite3 and not mysql Commented Jul 15, 2016 at 3:50
  • just answered your question... pls upvote and mark as correct answer if I helped you Commented Jul 15, 2016 at 4:05
  • VALUES (?) you still need to change to VALUES (?1,?2) Commented Jul 15, 2016 at 4:53
  • Pls add to the question the table's CONSTRAINTs? Commented Jul 15, 2016 at 4:54

1 Answer 1

4

You have to enumerate the values in the order of their appearance:

db.run("INSERT INTO test (num1, num2) VALUES (?1,?2)");

That's why only one variable is detected instead of the expected two.

Reference here.

One more way to do it:

// create the table
db.run('CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, num1 INTEGER NOT NULL, num2 INTEGER NOT NULL)')

var params = [[1,2],[3,4],[5,6],[7,8]];
db.serialize(function() {
    db.run("begin transaction");

    for (var i = 0; i < params.length; i++) {
        db.run("insert into data(num1, num2) values (?, ?)", params[i][0], params[i][1]);
    }

    db.run("commit");
});

reference: https://gist.github.com/NelsonMinar/2db6986d5b3cda8ad167

Sign up to request clarification or add additional context in comments.

4 Comments

Hmm. Still doesn't seem to be working, but I have a separate error now. The values I'm inserting have a NOT NULL constraint, which is failing when I insert. Makes me thing that passing in [params] is not working properly.
@JohnPalmer I'm almost sure the code is fine, you should print the new error after the ?1,?2 I think I can help
Yeah based on that reference link, it doesn't look like that's the right fix. You can bind the values separately, but you can't pass an array with the values for multiple inserts.
I don't think that's valid. It's not using the prepared statement at all, and doesn't give access to all of the ID's at one time once the inserts are complete. I already know I could run inserts sequentially and do something with the ID's one-by-one. But I want to be able to pass them to a callback function in an array at one time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.