【问题标题】:How to bind to IN parameters in Cloud Spanner Java API如何在 Cloud Spanner Java API 中绑定 IN 参数
【发布时间】:2017-04-24 11:42:41
【问题描述】:

是否可以使用 Google Cloud Spanner Java SDK 绑定到提供给查询的 IN 部分的参数?

例如

List<String> names = new ArrayList<String>();
names.add("Alice");
names.add("Bob");
String sql = "SELECT * FROM people WHERE name IN (@names)";
Statement statement = Statement
                .newBuilder(sql)
                .bind("names").to(names)
                .build();

如果我们使用 toStringArray 绑定名称,则会出错。如果我们设置以下内容:

names = "'Alice','Bob'";

那么生成的SQL就是:

SELECT * FROM people WHERE name IN ("'Alice','Bob'")
  • 注意额外的引号。知道我们如何在没有 %s 字符串替换的情况下避免注入攻击吗?

【问题讨论】:

  • 当你说“它错误”时,错误是什么?你在做.bind("names").toStringArray(names)
  • 嗨 Dan,我收到此错误:INVALID_ARGUMENT: No matching signature for operator IN for argument types STRING 和 {ARRAY} [at 1:35] SELECT name FROM customers WHERE name IN (@名称)
  • 如果你的SQL语句到WHERE name IN UNNEST(@names)会发生什么
  • 那行得通。这是首选方式吗?
  • 不知道,我阅读了 Spanner 的服务器代码以发现这一点,我已经 ping 过 Spanner 的技术作家,看看这是否只是想要记录,或者客户端库是否应该展开数组以重复参数.

标签: java sql google-cloud-platform google-cloud-spanner


【解决方案1】:

对您的代码进行 2 处更改:

List<String> names = new ArrayList<String>();
names.add("Alice");
names.add("Bob");
String sql = "SELECT * FROM people WHERE name IN UNNEST(@names)";
Statement statement = Statement
                .newBuilder(sql)
                .bind("names").toStringArray(names)
                .build();

首先是设置条件IN UNNEST,因为我们将绑定一个数组而不是重复值。

二是把to改成toStringArray,按照你原来的尝试绑定数组。

为了更好地可视化这一点,您绑定的数组本质上是这样的:

SELECT * FROM people WHERE name IN UNNEST(["Alice", "Bob"])

【讨论】:

    猜你喜欢
    • 2017-07-07
    • 1970-01-01
    • 2020-01-14
    • 2011-03-23
    • 2017-08-17
    • 1970-01-01
    • 2018-06-06
    • 2017-07-06
    • 1970-01-01
    相关资源
    最近更新 更多