将伪代码转换为SQL脚本

时间:2012-11-17 04:02:07

标签: sql postgresql foreign-keys referential-integrity

所以我有两张桌子:

  1. Bookmarks有几列[id等]
  2. Person_Bookmark有2列[personId,bookmarkId]
  3. 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 [edit] SQL脚本。

3 个答案:

答案 0 :(得分:5)

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

好像你想删除与不存在的书签的所有关联(更多) 以下列形式定义foreign key constraint

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.bookmarkid会更改bookmarks.id中相应的 当您更改ON DELETE CASCADE中的条目时,

  • person_bookmarks.bookmarkid会在bookmarks.id中删除相应的

其他选项可用read the manual.

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行。取消最后一行以取消死人。

答案 1 :(得分:2)

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

delete pb
from
  person_bookmark pb
where not exists (select 1 from booksmarks b where b.id = pb.bookmarkid)

答案 2 :(得分: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

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