I have an API through Firebase Functions. When sending an request to the API with the body {"name":"1234"} with postman. I get the error 401 "SQL : Error: Too many arguments"
This is my function: index.js
const functions = require("firebase-functions");
const mysqlx = require("@mysql/xdevapi");
exports.getUser = functions.https.onRequest(async (req, res) => {
const name = req.body.name;
functions.logger.info("name: ", name);
functions.logger.info("name type: ", typeof name);
try {
const session = await mysqlx.getSession({
user: "user",
password: "secretpassword",
host: "hostname",
schema: "database",
port: 33060,
});
session.sql("USE database").execute().then(() => {
const sql = "SELECT * FROM database.users WHERE user_name = ?";
session.sql(sql).bind(1, name).execute()
.then((result) => {
res.status(200).send("User gathered: " + result);
}).catch((err) => {
functions.logger.info("sql statement: ", sql);
functions.logger.error("err: ", err);
res.status(401).send("SQL : " + err);
});
}).catch((err) => {
functions.logger.error("err: ", err);
res.status(402).send("Session Error:" + err);
});
} catch (error) {
functions.logger.error("error: ", error);
res.status(500)
.send("An error occurred while fetching data from the database: " + error);
}
});
I have tried binding the variable by setting user_name
to both user_name = ?
and user_name = :name
. Setting user_name
to ?
when trying to bind resulted in a timeout in all cases except the one in my included codeblock. Setting user_name
to :name
resulted in all cases in the error specified in my question. I've tried binding using all these methods:
.bind("name": name)
.bind(name)
.bind([name])
My expected result is a response of the row where the user_name column matches the input name. From there I plan to extract data from the user row, of which code I have not included.
I have multiple loggers throughout the code, these are the logged values:
functions.logger.info("name: ", name);
logs: name: 1234
functions.logger.info("name type: ", typeof name);
logs: name type: string
functions.logger.info("sql statement: ", sql);
logs:
sql statement: SELECT * FROM database.users WHERE user_name = ?
functions.logger.error("err: ", err);
logs:err: Error: Too many arguments
at SqlResultHandler.BaseHandler.<computed> (/workspace/node_modules/@mysql/xdevapi/lib/Protocol/InboundHandlers/BaseHandler.js:121:17)
at Array.entry (/workspace/node_modules/@mysql/xdevapi/lib/Protocol/InboundHandlers/BaseHandler.js:92:29)
at WorkQueue.process (/workspace/node_modules/@mysql/xdevapi/lib/WorkQueue.js:77:19)
at Client.handleServerMessage (/workspace/node_modules/@mysql/xdevapi/lib/Protocol/Client.js:169:21)
at Client.handleNetworkFragment (/workspace/node_modules/@mysql/xdevapi/lib/Protocol/Client.js:213:14)
at TLSSocket.<anonymous> (/workspace/node_modules/@mysql/xdevapi/lib/DevAPI/Connection.js:800:34)
at TLSSocket.emit (node:events:513:28)
at TLSSocket.emit (node:domain:552:15)
at addChunk (node:internal/streams/readable:315:12)
at readableAddChunk (node:internal/streams/readable:289:9) {
info: {
severity: 0,
code: 5015,
sqlState: 'HY000',
msg: 'Too many arguments'
}
}
The number of arguments exceeds the number of placeholders in the SQL statement. In your case, the statement specifies one placeholder and you
provide two arguments via bind(1, name)
.
As described in the X DevAPI user guide, named placeholders are
supported only for CRUD statements, whereas SQL statements only support ordinary placeholders, so, in this case, both bind(name)
and bind([name])
should
work.
Disclaimer: I'm the lead developer of the MySQL X DevAPI connector for Node.js