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实现这一点。事实上,我就是这么做的。