Esqueleto:如何使用联接删除项目

Posted

技术标签:

【中文标题】Esqueleto:如何使用联接删除项目【英文标题】:Esqueleto: How can I delete an item using a join 【发布时间】:2015-09-29 03:55:22 【问题描述】:

是否可以使用 esqueleto 进行以下查询?

DELETE Table1
FROM Table1
INNER JOIN Table2 ON Table1.ID = Table2.ItemID

我试过了:

delete $ 
  from $ \(table1 `InnerJoin` table2) -> 
    on (table1 ^. Table1ID  ==. table2 ^. Table2ItemID)

奇怪的是,它产生了我在 Haskell 中见过的仅有的运行时错误之一

ERROR:  syntax error at or near "INNER"
LINE 2: FROM "table1" INNER JOIN "table2" ON "tab...

(基本上,很不高兴DELETE 缺少“table1”)

我还尝试向 monad 添加返回值,这与 select 一样可能会添加该缺失值。但这失败了,因为 delete 需要 m () 类型的 monad。

这可能只是 Esqueleto 缺少的吗?

【问题讨论】:

我不是 SQL 专家,但 DELETE FROM table1 INNER JOIN table2 看起来不是有效的 SQL 语句,或者至少不是标准的。例如 PostgreSQL 不支持它,并且手册建议使用子查询来完成它。 postgresql.org/docs/9.4/static/sql-delete.html @chi 没错,但DELETE table1 from table1 INNER JOIN table2(注意额外的table1)应该可以工作。我的问题是 Esqueleto 没有给我添加额外的table1 的方法。由于无法添加这个额外的参数,我尝试不添加,认为它可能会以某种方式添加,但它只是在编译时接受这种错误的语法,然后导致运行时错误。 从我链接的文档中,PostgreSQL 不支持 DELETEFROM 之间的任何内容。我同意 Esqueleto 应该表现得更好,在这里。 @chi 我做了一些进一步的研究,你是对的,这似乎是某些数据库(即 mysql)支持的扩展,但不在标准中,尤其是在 Postgresql 中。我不确定 Esqueleto 关于支持扩展的理念,但事实证明,我实际上使用的是 Postgresql(不知道你是怎么知道的 :)),所以没关系。既然这实际上为我结束了这个问题,请随时将您的评论升级为解决方案,我会给您信用.... 【参考方案1】:

我认为现在回答这个问题已经很晚了,但你可以使用 EXISTS

DELETE Table1
WHERE EXISTS (SELECT * FROM Table2 WHERE Table1.ID = Table2.ItemID)

【讨论】:

【参考方案2】:

试试这个。

delete $
from $ \(table1 `InnerJoin` table2) -> do
on (just (table1 ^. Table1ID  ==. table2 ^. Table2ItemID)

【讨论】:

【参考方案3】:

在 MS SQL 中,您可以使用以下方式使用连接删除表

DELETE Table1,Table2  FROM Table1 INNER JOIN Table2
WHERE Table1.Id1= Table2.Id1 and Table1.Id1= '1'

【讨论】:

我认为您错过了问题的重点......问题是,如何将此 SQL 查询转换为 Esqueleto。这似乎是不可能的。 哦,对不起……我不熟悉 Esqueleto。 . m sql 一个人

以上是关于Esqueleto:如何使用联接删除项目的主要内容,如果未能解决你的问题,请参考以下文章

用 esqueleto 计算行数

Haskell:Yesod 和 Esqueleto

使用 Esqueleto 处理列表类型

尝试使用我的模型设置 Esqueleto 时出错

如何将此 SQL 内部联接查询转换为 LINQ 语法?

在SQL左联接中删除重复项