SQL - 用参数值替换占位符

Mar*_*rco 7 sql postgresql kotlin

我有一个生成 SQL 字符串的函数。查询工作正常,我获取了我需要的数据。我遇到的问题是,我正在将查询构建为字符串,该字符串容易受到 SQL 注入攻击。我uuids在下面的示例中作为参数传递,但不传递元组。对于元组,我只是构建一个字符串输入。它看起来像这样:

private fun generateSQLForTuples(tuplesList: List<List<String>>):String =
    """
      select id, subcustomer
      from customer
      where uuid = any(:uuids)
      union
      select id, subcustomer
      from customer
      where (customer_id, subcustomer) in (${toJdbcTuples(tuplesList)})
    """.trimIndent()
Run Code Online (Sandbox Code Playgroud)

因为,我没有找到正确的元组 jdbc 数据类型,所以我生成一个字符串并直接使用toJdbcTuples(tuplesList)函数传递它。现在,由于我希望获得某种针对 SQL 注入攻击的保护,因此我想到首先为元组创建一个占位符列表,如下所示:

((?, ?), (?, ?))
Run Code Online (Sandbox Code Playgroud)

然后我会创建一个列表来匹配占位符。这是我创建占位符和元组的代码:

val placeholdersForTuples = customers.map { listOf("?", "?") }
val tuples = customers.map { listOf(it["customerId"] as String, it["subCustomer"] as String) }
val existingCustomers = fetchRows(
      ctx, generateSQLForTuples(placeholdersForTuples), mapOf("uuids" to customers.map { it["uuid"] })
  )
Run Code Online (Sandbox Code Playgroud)

但是,我不确定应该如何将包含实际元组值的列表作为参数传递到带有占位符的准备好的语句中?我已经将一个命名参数传递uuids给使用生成的fetchRows函数。我怎样才能为元组占位符做到这一点?SQLgenerateSQLForTuples(tuples)

Luk*_*zda 0

另一种方法可以是将多个输入元组作为 JSON(字符串参数)传递,并JSON_TO_RECORDSET在 SQL 端解析它:

SELECT s.customer_id, s.subcustomer
FROM json_to_recordset('[{"customer_id":1, "subcustomer":"a"},{"customer_id":3, "subcustomer":"c"}]'::json) 
     AS s(customer_id INT, subcustomer TEXT);
Run Code Online (Sandbox Code Playgroud)

完整演示:

SELECT *
FROM customer
WHERE (customer_id, subcustomer) in 
   (SELECT s.customer_id, s.subcustomer 
    FROM json_to_recordset('[{"customer_id":1, "subcustomer":"a"},{"customer_id":3, "subcustomer":"c"}]'::json) AS s(customer_id INT, subcustomer TEXT)
   )
Run Code Online (Sandbox Code Playgroud)

输入:'[{"customer_id":1, "subcustomer":"a"},{"customer_id":3, "subcustomer":"c"}]'应在应用程序端构建

db<小提琴演示