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

PostgreSQL-执行选择时检查外键是否存在,sql,postgresql,foreign-keys,Sql,Postgresql,Foreign Keys,假设我有以下数据: 表一些表: some_table_id | value | other_table_id -------------------------------------- 1 | foo | 1 2 | bar | 2 other_table_id | value ---------------------- 1 | foo 2 | bar 表其他表: some_tab

假设我有以下数据:

一些表

some_table_id | value | other_table_id
--------------------------------------
1             | foo   | 1
2             | bar   | 2
other_table_id | value
----------------------
1              | foo
2              | bar
其他表

some_table_id | value | other_table_id
--------------------------------------
1             | foo   | 1
2             | bar   | 2
other_table_id | value
----------------------
1              | foo
2              | bar
这里,
some_table
有一个外键,指向列
other_table\u id
other_table
进入某个名称的列

使用PostgreSQL中的以下查询:

SELECT * 
FROM some_table 
WHERE other_table_id = 3;
如您所见,
3
不存在于
other\u表中
此查询显然将返回0个结果

在不进行第二次查询的情况下,是否有办法知道我用作过滤器的外键在
其他_表中是否不存在


理想情况下,这是一个以后可以分析的错误(例如,当使用错误的外键执行
插入
更新
时发生的错误)。

如果对
某些表执行
插入
更新
,指定一个
other\u table\u id
值,而该值实际上不存在于
other\u table
中,则会因违反外键约束而产生错误<因此,代码>选择查询是您最关心的问题

使用
SELECT
查询解决问题的一种方法是将查询转换为与
other_table
执行外部联接,如下所示:

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;
如果任何
other\u table
行具有
other\u table\u id=3,则该查询将始终至少返回一行。在这种情况下,如果没有匹配的
some_table
行,那么它将只返回一行,该行的所有列
NULL
(假设它只从
some_table
中选择列),甚至是声明为非NULL的列


如果您希望这样的查询引发错误,那么您可能需要编写一个自定义函数来提供帮助,但这是可以做到的。我可能会在PL/pgSQL中实现它,使用该语言的
RAISE
语句。

您可以利用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;
创建或替换函数f\u从某些内容中选择(int)
将某些_表的集合返回为
$func$
开始
返回查询
选择*
从某张桌子上
其中,other_table_id=$1;
如果没有找到的话

使用不存在的其他\u表\u id>>%发出警告“呼叫请编辑您的问题并提供示例数据和所需结果。您的问题的答案是“是”,但您没有说明您想要这些信息的方式。编辑后,如果需要澄清,请告诉我。我也将使用plpgsql实现这一点。事实上,我就是这么做的。