【问题标题】:How to UPDATE in SQLite using a LEFT JOIN to select candidate rows如何使用 LEFT JOIN 在 SQLite 中更新以选择候选行
【发布时间】:2011-01-07 03:48:57
【问题描述】:

我有一个包含列的表 assoc

local_id, remote_id, cachedData

我可以成功运行如下 SQLITE 查询

SELECT a1.local_id, a1.remote_id FROM assoc a1 LEFT JOIN ....

以便我识别assoc 表中符合我的条件的某些行。

我想做的是在这些行中将cachedData 设置为null

我该怎么做? Sqlite 不支持带连接的 UPDATE;您可以发出子查询,但我不知道如何使语法正确;这对我来说似乎不直观。

【问题讨论】:

  • assoc 的主键是什么?
  • 这是 (local_id, remote_id) 对
  • 废话,我担心你会这么说。 :) 我已经asked this question 预计会出现这种情况。如果我收到货物,我会相应地更新我的答案。
  • 如果我能弄清楚如何通过 ALTER TABLE 添加一个自动递增的 id,我可以改用那个;我可以添加一个额外的列。
  • (例如,主键必须保留(local_id,remote_id),但我可以添加另一个键来消除歧义)

标签: sql sqlite join


【解决方案1】:
 UPDATE assoc SET cachedData = NULL
    WHERE EXISTS (SELECT * FROM otherTable 
        WHERE otherTable.Col1 = assoc.Col1 AND otherTable.Col2 = assoc.Col1)

请注意,这并不是特别高效。

【讨论】:

  • 你的技术在短期内对我有用,我认为 rowid 可能是长期使用的最佳选择。
  • 小心,ROWID 可以重复使用。您必须严格执行这种关系。
  • @Larry:“严格执行这种关系”——你能详细说明一下吗?如果这仅用于单个更新语句,是否存在使用不安全的可能性?
  • 如果要在关系的“主要”端删除行,但在“外部”端没有删除相应的行,则将新行添加回主端有指向新的主端记录的孤立的外部行。但是您有一个较早的问题,即如何在没有 JOINed 更新语法的情况下将主端记录的 ROWID 获取到外部表中。
  • 因此,如果这两个表不会添加或删除新行,那么您的技术是安全的,但只需将 UPDATE 问题提前一步,当您需要在两个表之间建立 ROWID 链接时表。
【解决方案2】:

如果assoc 有一个列作为主键(并假设它是local_id):

UPDATE assoc
SET cachedData=NULL
WHERE local_id IN (
  SELECT local_id FROM assoc a1 LEFT JOIN ...
);

【讨论】:

  • 如果它有多个列作为主键怎么办?
  • @JasonS 对于复合 PK 情况,恐怕我还没有答案。按照您上面的建议添加一个唯一的消歧键是一种解决方案。
【解决方案3】:

啊哈,已经有内置的rowid了!

UPDATE assoc
SET cachedData=NULL
WHERE rowid IN (
   SELECT rowid FROM assoc a1 LEFT JOIN ...
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2020-08-02
    • 1970-01-01
    • 2012-07-15
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多