miniflare
miniflare copied to clipboard
Error: D1_ERROR: Wrong number of parameter bindings for SQL query.
Hi Team - I believe I'm experiencing the same issue identified in 504 where I'm getting the following error when attempting to Insert into D1. I understand a new Miniflare release should have fixed this issue.
✘ [ERROR] Error processing request: Error: D1_ERROR: Wrong number of parameter bindings for SQL query.
const sql = `
INSERT INTO Events (eventType, severity, eventId, source, eventTime, eventTimeUK, timeCreated)
VALUES (?, ?, ?, ?, ?, ?, ?)
`;
const parameters = [eventType, severity, eventId, source, eventTime, eventTimeUK, timeCreated]; // these are defined on the fly
const result = await db.prepare(sql).run(parameters);
I'm using ⛅️ wrangler 3.22.4. Perhaps I'm doing something wrong but any assistance would be greatly appreciated.
Many thanks for any comments in advance.
Alex.
Hey! 👋 Thanks for raising this. Does this code work for you when deployed to production? Could you share the version
of your database from wrangler d1 info <database_name>
too?
I just hit this as well. It also happens in production. I am running wrangler 3.50.0
. There doesnt appear to be a version in the output from wrangler d1 info
, but my created_at
is 2023-09-29T23:08:01.953Z
.
Sample query I am trying to parameterize:
const limit = ctx.query.limit || 25
const page = (ctx.query.page || 0) * limit
const sql = oneline`
SELECT t.id, t.name, t.description, t.shareLink, a.avatar, a.firstName, a.lastName FROM templates t
LEFT JOIN accounts a ON t.ownerId = a.id
INNER JOIN templates_fts s ON s.id = t.id
WHERE templates_fts MATCH '{name description}: ?'
ORDER BY bm25(templates_fts, 0, 2, 1)
LIMIT ?
OFFSET ?;
`
const result = await ctx.env.DB.prepare(sql)
.bind(ctx.query.query, limit, page)
.run()
Results in this error: D1_ERROR: Wrong number of parameter bindings for SQL query.
Query works fine when it isn't parameterized. I guess for now I can manually sanitize the input, but would be nice to have this fixed.
Let me know if you want me to open this issue in the workerd repo.
Hey I just hit this as well, after bashing it around for longer than needed, co-pilot did a sneaky typeahead with the three dots to de-structure and it seems to have worked:
Example:
let deleting = ['test1', 'test2']
const records = await c.env.DB.prepare(`SELECT * FROM table WHERE column IN (${deleting.map(() => '?').join(', ')})`)
.bind(...deleting)
.run()
console.log('Records::', records)
@seivad I'll try spreading an array into bind tomorrow and report back. Thanks for sharing!
Didn't work for me. Didn't really expect it to... would have been surprised if it did.
@SupremeTechnopriest I had this issue late last night but realised that the were a couple of quotes that were messing with the query. I'd look at the WHERE templates_fts MATCH '{name description}: ?'
because I'm assuming ctx.query.query
is also a string and it might not get formatted correctly.
@matthewlynch InterestingI Yes it is also a string. How did you solve it on your end?
The query definitely needs the quotes... It looks like the ? isn't being parsed out properly when its inside quotes. I think this is a bug in D1.
@SupremeTechnopriest Can you log the value of sql
and ctx.query.query
? My assumption, based off the code you provided is that there are additional quotes being injected in the first parameter binding.
I noticed my issue when I started logging the queries being sent to D1 via the ORM I am using (Drizzle).
@matthewlynch
SQL:
SELECT t.id, t.name, t.description, t.shareLink, a.avatar, a.firstName, a.lastName FROM templates t
LEFT JOIN accounts a ON t.ownerId = a.id
INNER JOIN templates_fts s ON s.id = t.id
WHERE templates_fts MATCH '{name description}: ?'
ORDER BY bm25(templates_fts, 0, 2, 1)
LIMIT ?
OFFSET ?
ctx.query.query:
foo
The query is a user's search term. So in theory this could be anything. I would expect that the parameterized query would sanitize and escape the input.
I am also using drizzle, but to rule out any weirdness there I went direct to the database. Drizzle doesnt support virtual tables, so I would have to use:
sql``
For now I have to use sql.raw()
to make this query work.