我正在尝试使用Node.js中的Cloud Spanner lib向我的扳手查询中动态添加一个LIMIT
和一个ORDER BY
子句:
function getPosts (query) {
const { limit, start, sortBy, sortOrder } = query;
delete query.start;
delete query.limit;
delete query.sortBy;
delete query.sortOrder;
const meta = {};
let limitClause = '';
let sortClause = '';
if (limit) {
limitClause = `
LIMIT @limit
OFFSET @start
`;
meta.limit = limit && parseInt(queryObj.limit, 10);
meta.start = start ? parseInt(start, 10) : 0;
}
if (sortBy) {
sortClause = `ORDER BY @sortBy ${(sortOrder && sortOrder.match(/^desc/i)) ? 'DESC' : 'ASC'}`;
meta.sortBy = sortBy;
}
const [postsRows] = await myDatabase.run({
sql: `
SELECT *
FROM posts@{FORCE_INDEX=posts_userId}
WHERE userId = @userId
${sortClause}
${limitClause}
`,
params: { userId, ...meta },
});
return orderRows;
}
请注意,myDatabase
是Spanner的一个实例。 (https://cloud.google.com/nodejs/docs/reference/spanner/2.0.x/Spanner)
目前,LIMIT
子句按预期工作,但响应似乎像ORDER BY
子句被忽略。
如果我将第二个if语句替换为
if (sortBy) {
sortClause = `ORDER BY ${sortBy} ${(sortOrder && sortOrder.match(/^desc/i)) ? 'DESC' : 'ASC'}`;
}
然后它可以按预期工作,但是我不想像这样将原始字符串插入到我的查询中。
我不确定参数是如何插值到查询中的,但是它可以用于userId,limit和start变量。
查看Spanner实例的run方法生成的插值结果也很有帮助,我不确定是否/如何查看。
答案 0 :(得分:5)
来自Cloud Spanner的documentation on query parameters:
查询参数可用于替换任意表达式。 但是,它们不能用于替换标识符,列 名称,表名或查询本身的其他部分。
ORDER BY表达式是列名,不是查询参数的受支持类型。在这种情况下,您需要插入查询字符串。