Does SQLite3 have prepared statements in Node.js?
According to the node-sqlite3 API documentation, you can use parameters in your SQL queries in several different ways:
// Directly in the function arguments.
db.run("UPDATE tbl SET name = ? WHERE id = ?", "bar", 2);
// As an array.
db.run("UPDATE tbl SET name = ? WHERE id = ?", [ "bar", 2 ]);
// As an object with named parameters.
db.run("UPDATE tbl SET name = $name WHERE id = $id", {
$id: 2,
$name: "bar"
});
NodeJS SQLite3 prepared statement with IN and AND
pass values as an array:
let query = db.prepare(`SELECT * FROM words WHERE word IN (${wordMap}) AND language = ?`, [...words, language]);
How to use Prepared statements with npm sqlite library on node js
I don't know the sqlite
library too well, but the following example from the documentation performs a parameterised INSERT
statement:
const result = await db.run('INSERT INTO tbl(col) VALUES (:col)', {
':col': 'something'
})
I think you're focusing on the phrase 'prepared statement' a little too much.
Instead of looking only for this exact phrase, look for any use of parameters whose values are passed separately to the main SQL string. The example above fits this: there is a parameter :col
which appears in the SQL string and the value for it is provided in an object passed to db.run
alongside the SQL string.
Preparing statement with input in Nodejs and Sqlite3
I think you almost had it with your db.all call. Try passing your user value as a parameter:
db.all(
'SELECT * FROM MyTable WHERE userId=?',
someUserInput,
function(err, rows) { /* Do something here */});
Source:
https://github.com/mapbox/node-sqlite3/wiki/API#databaseallsql-param--callback
how to correctly serialize db.prepare in nodejs sqlite3
This is an old question, but since I had the same question and came across this page years later, I thought I'd take a stab at my understanding:
db.serialize will serialize the queries. That means that if there's a query running, other queries will be queued up and run later, so you get an assurance that the queries run in the order they were presented. But that doesn't mean the JS code itself is blocked. Your code assumes that db.serialize causes database calls to be blocking (synchronous). I believe the problem is here:
var count=0;
[...]
var stmt = db.prepare("INSERT INTO info VALUES (?)");
stmt.run('Lorem ipsum '+(count+1));
specifically, this second statement will be queued up to run after the previous statement. However, while that is true of the statement, the evaluation of (count+1) already happened. That means that count was initialized to 0, a (slow) database query was run, and a statement was queued up using count+1. Since the computation of count+1 didn't wait for the query to finish, count's original value (0) is used and you are effectively queuing up:
INSERT INTO info VALUES ('Lorem ipsum ' + (0 + 1))
which explains why you always see "Lorem ipsum 1".
I believe the fix for this is to queue up the second sql statement in the callback of the first. Only then will you be assured that count will have been updated correctly.
Of course, another fix would be to construct an INSERT statement that uses SQL to compute the count directly, but I'm assuming that you created this artificial example to prove a point.
Sauce
SQLite3 + Node.js - Should I open and close the database for each INSERT or keep it always open?
Constantly opening and closing the db connection isn't going to help your concurrency problem and isn't very efficient. Leave it open.
WAL mode lets you have one writer and multiple readers at the same time. Other journal modes let you have multiple active readers at the same time with no writers, or one writer and no readers until the writer is finished. So if the other application using the database is only a reader, WAL is probably going to be what you want.
Anything that tries to read or write the database can be written so if it gets a locking error, it tries again after a brief pause before eventually giving up after a few failed attempts (The C api has a way to do this automatically, not sure about Node, but there's always the busy_timeout pragma).
You should also make sure that any prepared statements you execute are reset or finalized when you're done with them so they release locks and allow other queries to run.
If it's still a problem after all that, you might need a different database.
Node.js sqlite3 IN operator
db.all('SELECT email ' +
'FROM users' +
'WHERE email in ( ' + friends.map(function(){ return '?' }).join(',') + ' )',
friends,
function(err, rows) {
if (!err) {
Related Topics
SQL Pulling a Row for Next or Previous Row of a Current Row
How to Detect If a String Contains Special Characters
Running Total by Grouped Records in Table
Is There an Oracle Equivalent to SQL Server's Output Inserted.*
How to Get the Next Number in a Sequence
Icalendar "Field" List (For Database Schema Based on Icalendar Standard)
SQL Distinct for 2 Fields in a Database
No Unique or Exclusion Constraint Matching the on Conflict
Using Django How to Combine Two Queries from Separate Models into One Query
Return All Possible Combinations of Values Within a Single Column in SQL
Storing Datetime (Utc) VS. Storing Datetimeoffset
How to Setup a Linked Server to an Oracle Database on SQL 2000/2005