PostgreSQL - 执行 SELECT 时检查外键是否存在

lan*_*nte 2 sql postgresql foreign-keys

假设我有以下数据:

some_table

some_table_id | value | other_table_id
--------------------------------------
1             | foo   | 1
2             | bar   | 2
Run Code Online (Sandbox Code Playgroud)

other_table

other_table_id | value
----------------------
1              | foo
2              | bar
Run Code Online (Sandbox Code Playgroud)

在这里,some_table有一个外键列other_table_idother_table某个名称的列进入。

在 PostgreSQL 中使用以下查询:

SELECT * 
FROM some_table 
WHERE other_table_id = 3;
Run Code Online (Sandbox Code Playgroud)

如您所见,3不存在于other_table此查询显然将返回 0 个结果。

在不进行第二次查询的情况下,有没有办法知道我用作过滤器的外键是否有效地不存在于other_table?

理想情况下,作为稍后可以解析的错误(例如,在使用错误的外键执行 anINSERT或 anUPDATE时会发生这种情况)。

Erw*_*ter 5

你可以利用 PL/pgSQL 的一个特性来非常便宜地实现它:

CREATE OR REPLACE FUNCTION f_select_from_some_tbl(int)
  RETURNS SETOF some_table AS
$func$
BEGIN
   RETURN QUERY
   SELECT * 
   FROM   some_table 
   WHERE  other_table_id = $1;

   IF NOT FOUND THEN
      RAISE WARNING 'Call with non-existing other_table_id >>%<<', $1;
   END IF;
END
$func$  LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

RETURN;在这种情况下,final是可选的。

WARNING,如果您的查询不返回任何行,才会引发。我没有ERROR在示例中提出 an ,因为这会回滚整个事务(但如果它符合您的需要,您可以这样做)。

我们在Postgres 9.3 的手册中添加了一个代码示例来演示这一点。