如何在 slick 中使用 sql""" 插值编写动态 SQL 查询

Posted

技术标签:

【中文标题】如何在 slick 中使用 sql""" 插值编写动态 SQL 查询【英文标题】:How to write dynamic SQL queries with sql""" interpolation in slick 【发布时间】:2015-02-04 09:47:31 【问题描述】:

我是 Scala 和 Slick 的新手,我正在尝试使用 Slick 插值编写一个普通的 SQL 查询。

案例 1: 我想要概括代码,以便将查询存储为常量。

例如:

val SQL_ALL_TABLE_METADATA: String = """SELECT DISTINCT table_name, column_name, data_type
                                            FROM information_schema.columns
                                                    WHERE table_schema = 'apollo' OR table_schema = 'dpa' ORDER BY table_name""";

并从类似的常量创建普通查询

var plainQuery = sql"""$SQL_ALL_TABLE_METADATA""".as[List[String]]

案例 2: 替换部分查询

例如:从表 'table1' 中获取列 f_name 的信息

var column= "f_name"
var plainQuery = sql"""SELECT $column FROM table1""".as[String]

当我尝试上述情况时,它不起作用,因为查询似乎在编译时静态绑定。

请注意,目前我想使用纯 SQL 并在未来使用高级 Slick API。

【问题讨论】:

【参考方案1】:

案例一

为什么不简单地拥有这个?

val SQL_ALL_TABLE_METADATA: StaticQuery = sql"""SELECT DISTINCT table_name, column_name, data_type
                                            FROM information_schema.columns
                                                    WHERE table_schema = 'apollo' OR table_schema = 'dpa' ORDER BY table_name"""

var plainQuery = SQL_ALL_TABLE_METADATA.as[List[String]]

案例 2

Use #$ instead of $

var column= "f_name"
var plainQuery = sql"""SELECT #$column FROM table1""".as[String]

【讨论】:

案例 2 中的插值是否经过消毒?如果没有,有没有办法清理我们要使用 #$ 插入的字符串? @ciuncan 不,它没有经过消毒。我无法回答你的第二个问题。它可以是任何东西:列名、表名、模式、查询、查询的一部分…… @Dimitri 啊,你是对的。在我的情况下,它是列名和生成常量列值的字符串文字。它是否也依赖于数据库,或者 jdbc 只是处理它?如果是这种情况,我正在使用 Postgresql。 (编辑:我认为 jdbc 可以有一些方法来清理这些字符串以进行插值) @ciuncan 对不起,我不知道这个功能是否可用。 好的,谢谢。对于任何需要这种东西的人,我在 JdbcDriver 驱动程序特征中找到了 quoteIdentifier 函数,我认为它应该对转义列名和表名很有用。如果我发现任何相关内容,我会进一步查看并在这里报告。【参考方案2】:

我正在发布不使用插值的答案,也许有人觉得它有帮助。

我在测试中就是这样解决的,executeUpdate 方法返回查询的实际结果。 我能够从字符串变量进行动态查询。

dbConnection = JdbcBackend.Database.forURL(url = dbConfig.getString("db.url"), driver = "org.h2.Driver")
val createTablesSqlQuery:String = //read_from_file
dbConnection.createSession().createStatement().executeUpdate(createTablesSqlQuery)

有用的话题是这个: https://groups.google.com/forum/#!topic/scalaquery/OxAgtcCPMyg

【讨论】:

【参考方案3】:

实现案例 2 的方法是这样的:

var plainQuery = sql"""SELECT $column.unsafesql FROM table1""".as[String]

【讨论】:

以上是关于如何在 slick 中使用 sql""" 插值编写动态 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

Slick 3 - 如何在使用纯 SQL 插入时获得正确的(数据库)架构

如何使用 slick 进行聚合

Slick:如何将 SQL LIKE 语句与 SQL IN 语句结合使用

slick for play 使用原生sql查询以及拼接sql

在 Slick 中查看 SQL 查询

使用 Play Slick 在 PostgreSQL 中持久化 UUID - java.sql.BatchUpdateException