在Slick

时间:2016-02-02 14:17:14

标签: sql scala slick slick-3.0

我想将SQL查询转换为TableQuery

SELECT ..., TRIM(LEADING '0' FROM mycolumn) FROM mytable WHERE TRIM(LEADING '0' FROM mycolumn) = '$key

应该成为MyTableQuery.filter(<_.mycolumn something something> )

我无法使用implicit MappedColumnType,因为我从String映射到String并在结果中包含其他String列。我不知道如何在SELECTWHERE

中使用它

对于SELECT部分,我创建了一个自定义函数,用于将结果元组映射到我的case类,因此我只需要WHERE部分的解决方案。

已阅读文档中的Coming from SQLUser defined features,但不幸的是,我不是更聪明的人。我想我可以使用SimpleFunction.unary[String, String],但还没弄明白。

我会使用String修剪常规dropLeft,但是Rep[String]没有这样的方法。 ltrim不接受参数。 endsWith在我的案例中含糊不清。

我无法填充查询String,因为数据库中的所有值都没有填充且长度不同。

我绝对可以使用纯SQL并映射结果,但我真的很想了解我在这里缺少的内容。

我正在使用Slick 3.1.1

1 个答案:

答案 0 :(得分:3)

TRIM略显奇怪的语法(LEADING意味着您必须使用SimpleExpression并使用可以访问的QueryBuilder。

val trimLeading = SimpleExpression.binary[String, String, String] {
  (trimChar, str, queryBuilder) =>
    import slick.util.MacroSupport._
    import queryBuilder._
    b"TRIM(LEADING $trimChar FROM $str)"
}

这是一个练习它的例子

import com.typesafe.config.ConfigFactory
import slick.backend.DatabaseConfig
import slick.driver.JdbcProfile
import scala.concurrent.duration.Duration
import scala.concurrent.Await

object TrimLeading extends App {
  def trimLeadingExample(dbConfig: DatabaseConfig[JdbcProfile]): Unit = {
    import dbConfig.driver.api._
    val trimLeading = SimpleExpression.binary[String, String, String] {
      (trimChar, str, queryBuilder) =>
        import slick.util.MacroSupport._
        import queryBuilder._
        b"TRIM(LEADING $trimChar FROM $str)"
    }

    class ZeroTable(tag: Tag) extends Table[String](tag, "ZeroTable") {
      def zeros = column[String]("zeros")
      def * = zeros
    }
    val zeroTable = TableQuery[ZeroTable]
    exec(zeroTable.schema.create)
    exec(zeroTable ++= Seq("000000x", "00x", "000000000x", "00000x", "00xx"))

    exec(zeroTable.
          filter(s => trimLeading("0", s.zeros) === "x").
          map(s => trimLeading("0", s.zeros)).result).foreach(println)
    exec(zeroTable.schema.drop)
    def exec[T](action: DBIO[T]): T = Await.result(dbConfig.db.run(action), Duration.Inf)
  }
  val configStr =
    """
      |  driver = "freeslick.OracleProfile$"
      |  db {
      |    driver = oracle.jdbc.OracleDriver
      |    url="jdbc:oracle:thin:@//localhost:49161/xe"
      |    properties = {
      |      databaseName = "freeslicktest"
      |      user = "system"
      |      password = "oracle"
      |    }
      |  }
    """.stripMargin
  trimLeadingExample(DatabaseConfig.forConfig[JdbcProfile]("", ConfigFactory.parseString(configStr)))
}

并且从日志中,语句是

*** (s.jdbc.JdbcBackend.statement) Preparing statement: select TRIM(LEADING '0' FROM "zeros") from "ZeroTable" where TRIM(LEADING '0' FROM "zeros") = 'x'