如何使用 slick 在 scala 中传递变量作为记录删除的一部分

问题描述 投票:0回答:1

我有一个 scala 方法用于删除 postGres 中的记录。这也使用了 scala-slick。最初的实现效果很好。这是该实现:

def deleteRecord(username: String, id: String, mappingRequest: MappingRequest): DBIO[Option[String]] = {
val tbl = MySchema.fullTblName(config)
val action =
  sql"""
     DELETE FROM #$tbl WHERE (#${MySchema.columns.id}) = $id
     OR (SELECT false WHERE 'xusername' = $username)
     RETURNING #${MySchema.columns.id}, $username;
   """.as[(String, String)].headOption

  action.flatMap {
    case Some((result, returnedUserId)) =>
      DBIO.successful(Some(result))
    case None =>
      DBIO.failed(new Exception("Delete failed, probably due to id not found in table"))
  }
}

但是,我需要传递用户名作为操作的一部分,以便 postGres 触发器函数读取用户名值以添加到历史表中(用户名不是实际删除的一部分,因此我需要将其传递给触发功能以其他方式)。这是我的实施尝试:

def deleteRecord(username: String, id: String, mappingRequest: MappingRequest): DBIO[Option[String]] = {
    val tbl = MySchema.fullTblName(config)
    val setSessionVariable = sqlu"SET my_variable = $username"
    val deleteAction =
      sql"""
         DELETE FROM #$tbl WHERE (#${MySchema.columns.id}) = $id
         OR (SELECT false WHERE 'xusername' = $username)
         RETURNING #${MySchema.columns.id}, $username;
       """.as[(String, String)].headOption

    for {
      _ <- setSessionVariable
      actionResult <- deleteAction
    } yield actionResult match {
      case Some((result, returnedUserId)) =>
        Some(result)
      case None =>
        throw new Exception("Delete failed, probably due to id not found in table")
    }
  }

当我执行该方法时,我收到以下 sql 异常:

ERROR: syntax error at or near \"$1\"\n  Position: 19  Error Code: 42601"

显然这个查询(或双重查询)的构造有问题。我尝试找出它指的是哪一行,但我正在努力捕获包含变量替换的生成的 sql 语句的日志记录。

如果有人可以查看这段代码并告诉我我可能做错了什么,我将非常感激。归根结底,我只需要一些 scala/slick 实现来传递用户名,作为成功从表中删除记录的一部分,以便它可供我的触发器使用。

感谢您的任何想法。

更新我的帖子:为了尝试调试我的问题,我对 SET 语句进行了硬编码,如下所示:

val setSessionVariable = sqlu"SET my_variable = 'myUser'"

我现在遇到了不同的错误:

ERROR: unrecognized configuration parameter \"my_variable\"

由于我正在尝试创建会话变量,我很困惑为什么 postGres 会说“无法识别”。在为会话变量赋值之前,它是否必须存在?如果是这样,那么这意味着它存在于会话之外(或者至少这就是我解释错误消息的方式)。再次强调,任何想法或见解都将不胜感激。

scala slick
1个回答
0
投票

好的,这是解决方案。要使设置变量查询正常工作,唯一需要更改的是 scala-slick sqlu 行的语法。这是正确的语法: val setSessionVariable = sqlu"SET my.variable = '#$myUser'"

© www.soinside.com 2019 - 2024. All rights reserved.