在Node.js中使用Cloud Spanner进行插值查询

时间:2018-09-12 21:08:23

标签: node.js google-cloud-platform google-cloud-spanner

我正在尝试使用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方法生成的插值结果也很有帮助,我不确定是否/如何查看。

1 个答案:

答案 0 :(得分:5)

来自Cloud Spanner的documentation on query parameters

  

查询参数可用于替换任意表达式。   但是,它们不能用于替换标识符,列   名称,表名或查询本身的其他部分。

ORDER BY表达式是列名,不是查询参数的受支持类型。在这种情况下,您需要插入查询字符串。