批量删除行时不要拒绝整个语句

Yan*_*hon 5 postgresql postgresql-9.4

我有一个表,其目的是存储应用程序的各种图像。它是这样定义的:

CREATE TABLE images
(
  id lo NOT NULL,
  name character varying(1024) NOT NULL,
  type character varying(32) NOT NULL,
  dimension point,
  last_modified timestamp without time zone NOT NULL DEFAULT now(),
  CONSTRAINT "PK_images" PRIMARY KEY (id)
)
Run Code Online (Sandbox Code Playgroud)

其他一些表有外键引用images.id,如果图像在某处被引用,则不应删除该约束(即应用程序负责首先正确删除引用);

...
CONSTRAINT "FK_foo_image" FOREIGN KEY (image_id)
   REFERENCES images (id) MATCH SIMPLE
   ON UPDATE CASCADE ON DELETE RESTRICT
...
Run Code Online (Sandbox Code Playgroud)

由于许多表格行可能引用相同的图像,我需要自动清理不再有任何引用的图像。

我的第一个想法是实现应用程序以删除所有外键引用,然后删除与这些已删除外键的值匹配的所有图像。为此,我会images在删除之前在表上创建一个触发器,如果仅删除“孤立”图像之类的查询而其他查询将被静默忽略,则可以“吞下”所有约束异常。我只是不确定如何正确地做到这一点。

如果这个想法不好,还有什么其他(如果不是更好的话)替代方案?

基本上,如果我正在执行这样的查询

DELETE FROM images WHERE id IN (101, 102, 103, 104, 105)
Run Code Online (Sandbox Code Playgroud)

images.id102104具有约束,防止它们被删除了,我想所有其它图像仍然被删除。该DELETE查询应该是简单的,如上图所示。

谢谢你。

Yan*_*hon 2

我当前的解决方案涉及在每个表引用上创建一个触发器images,如下所示:

CREATE FUNCTION public.foo_images_cleanup() RETURNS trigger AS $$
BEGIN
  BEGIN
    DELETE FROM images WHERE id = OLD.image_id;
  EXCEPTION WHEN OTHERS THEN
    NULL;
  END;

  IF (TG_OP = 'DELETE') THEN
     RETURN OLD;
  ELSE
     RETURN NEW;
  END IF;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER foo_images_cleanup AFTER UPDATE OR DELETE ON public.foo_images
  FOR EACH ROW
  EXECUTE PROCEDURE public.foo_images_cleanup();
Run Code Online (Sandbox Code Playgroud)

我的目标不是性能,因为任何时候清理的图像(最多)不应超过几十个。