PostgreSQL - Check foreign key exists when doing a SELECT

非 Y 不嫁゛ 提交于 2019-12-07 02:06:28

You can exploit a feature of PL/pgSQL to implement this very cheaply:

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;

A final RETURN; is optional in this case.

The WARNINGis only raised if your query doesn't return any rows. I am not raising an ERROR in the example, since this would roll back the whole transaction (but you can do that if it fits your needs).

We've added a code example to the manual with Postgres 9.3 to demonstrate this.

If you perform an INSERT or UPDATE on some_table, specifying an other_table_id value that does not in fact exist in other_table, then you will get an error arising from violation of the foreign key constraint. SELECT queries are therefore your primary concern.

One way you could address the issue with SELECT queries would be to transform your queries to perform an outer join with other_table, like so:

SELECT st.* 
FROM
  other_table ot
  LEFT JOIN some_table st ON st.other_table_id = ot.other_table_id
WHERE st.other_table_id = 3;

That query will always return at least one row if any other_table row has other_table_id = 3. In that case, if there is no matching some_table row, then it will return exactly one row, with that row having all columns NULL (given that it selects only columns from some_table), even columns that are declared not null.

If you want such queries to raise an error then you'll probably need to write a custom function to assist, but it can be done. I'd probably implement it in PL/pgSQL, using that language's RAISE statement.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!