我有一个 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 sqlu 行的语法。这是正确的语法: val setSessionVariable = sqlu"SET my.variable = '#$myUser'"