2

所以我有两张桌子:

  1. Bookmarks有几列[id等]
  2. Person_Bookmark有 2 列 [personId, bookmarkId]

Bookmarks表示指向其他网站的链接。所有有效的书签都有一个 id。该Person_Bookmark表有一堆personIds和他们的书签,显示为bookmarkId

这是我的伪代码:

> let x = integer list of all bookmarkId's from Person_Bookmark
> 
> for each x  {   
>     if ('select * from 'Bookmarks' where 'id' = x returns 0 rows) {
>       delete from 'person_bookmark' where 'bookmarkId' = x
>     }
> }

请告诉我如何转换为 Postgres [编辑] SQL 脚本。

4

3 回答 3

5

@Jan 已经提到外键,但他的建议不完整。

似乎您想删除与不存在的书签的所有关联(不再存在)。
以以下形式定义外键约束

ALTER TABLE person_bookmarks
ADD CONSTRAINT pb_fk FOREIGN KEY (bookmarkid) REFERENCES bookmarks (id)
ON UPDATE CASCADE
ON DELETE CASCADE;
  • 这仅允许person_bookmarks.bookmarkid存在于 中的值bookmarks.id

  • ON UPDATE CASCADE当您更改条目时更改相应的person_bookmarks.bookmarkidbookmarks.id

  • ON DELETE CASCADE当您更改 中的条目时删除相应的person_bookmarks.bookmarkidbookmarks.id

其他选项可用,请阅读手册。

ON DELETE CASCADE子句自动执行,您尝试手动修复。在添加 fk 约束之前,您必须手动修复一次:

DELETE FROM person_bookmarks pb
WHERE NOT EXISTS (SELECT 1 FROM bookmarks b WHERE b.id = pb.bookmarkid);
-- OR NOT EXISTS (SELECT 1 FROM persons p   WHERE p.id = pb.personid);

删除所有不存在的行bookmarkid。取消注释最后一行以摆脱死人,也是。

于 2012-11-17T11:19:57.557 回答
2

这适用于 SQL Server - 不确定 MySQL ......

delete pb
from
  person_bookmark pb
where not exists (select 1 from booksmarks b where b.id = pb.bookmarkid)
于 2012-11-17T04:10:03.457 回答
0

@Derek 回复的另一个版本:

DELETE FROM person_bookmark 
WHERE bookmarkid NOT IN (SELECT id FROM bookmarks)

这样做的需要意味着您的表之间没有外键索引。我强烈建议你这样做。缺点(或功能)在于,例如当您删除一个person(我猜您的示例中存在此表)时,您必须先删除所有关联的数据,否则服务器将抛出错误。

像这样的东西:

DELETE FROM person_Bookmark WHERE personid = @personid
DELETE FROM person_SomeOtherTable WHERE personid = @personid
DELETE FROM person WHERE id = @personid

但优点是您的数据库中没有孤立行,并且您不能错误地输入错误数据(bookmarkperson不存在的 a 存储 a)。

于 2012-11-17T04:29:38.177 回答