Я хочу обновить этот простой sql запрос, пропустив первый N-й элемент. Но это очень специфично для БД: c.
Поскольку вы беспокоитесь об изменении SQL для разных баз данных, я предлагаю вам абстрагироваться от этой части SQL и решить, что делать на основе используемого профиля Slick.
Если вы работаете с несколькими продуктами баз данных, вы, вероятно, уже абстрагировались от какого-либо определенного c профиля, возможно, используя JdbcProfile
. В этом случае вы можете поместить своего помощника "skip N elements" в класс и использовать активный slickProfile
, чтобы выбрать SQL для использования. (В качестве альтернативы вы, конечно, можете проверить с помощью других средств, например, заданного вами значения среды).
На практике это может быть что-то вроде этого:
case class Paginate(profile: slick.jdbc.JdbcProfile) {
// Return the correct LIMIT/OFFSET SQL for the current Slick profile
def page(size: Int, firstRow: Int): String =
if (profile.isInstanceOf[slick.jdbc.H2Profile]) {
s"LIMIT $size OFFSET $firstRow"
} else if (profile.isInstanceOf[slick.jdbc.MySQLProfile]) {
s"LIMIT $firstRow, $size"
} else {
// And so on... or a default
// Danger: I've no idea if the above SQL is correct - it's just placeholder
???
}
}
Что вы можете сделать используйте как:
// Import your profile
import slick.jdbc.H2Profile.api._
val paginate = Paginate(slickProfile)
val action: DBIO[Seq[Int]] =
sql""" SELECT cols FROM table #${paginate.page(100, 10)}""".as[Int]
Таким образом, вы можете изолировать (и контролировать) спецификацию СУБД c SQL в одном месте.
Чтобы сделать помощника более удобным, и поскольку slickProfile
подразумевается, вы могли бы вместо этого написать:
def page(size: Int, firstRow: Int)(implicit profile: slick.jdbc.JdbcProfile) =
// Logic for deciding on SQL goes here
Я чувствую себя обязанным прокомментировать, что использование соединения (#$
) в простом SQL открывает вам для SQL атак инъекцией, если любое из значений предоставляется пользователем.