CREATE OR REPLACE FUNCTION union_foreign_tables(ft_info text[][])
RETURNS SETOF record
AS $$
DECLARE
ft_row text[];
ft_name text;
ft_col1 text;
ft_col2 text;
ft_col3 text;
ft_connected boolean;
first_table boolean := true;
query text := '';
i integer;
BEGIN
FOR i IN 1..array_length(ft_info, 1)
LOOP
ft_row := ft_info[i];
ft_name := ft_row[1];
ft_col1 := ft_row[2];
ft_col2 := ft_row[3];
ft_col3 := ft_row[4];
ft_connected := true;
BEGIN
EXECUTE format('SELECT 1 FROM %I LIMIT 1', ft_name);
EXCEPTION WHEN others THEN
ft_connected := false;
END;
IF ft_connected THEN
IF first_table THEN
query := format('SELECT %I AS col1, %I AS col2, %I AS col3 FROM %I', ft_col1, ft_col2, ft_col3, ft_name);
first_table := false;
ELSE
query := query || format(' UNION SELECT %I AS col1, %I AS col2, %I AS col3 FROM %I', ft_col1, ft_col2, ft_col3, ft_name);
END IF;
END IF;
END LOOP;
IF query <> '' THEN
RETURN QUERY EXECUTE query;
END IF;
END;
$$ LANGUAGE plpgsql;
2条答案
按热度按时间7lrncoxx1#
您可以尝试使用具有错误处理功能的函数或存储过程,沿着所示:
请注意,由于我不知道当前视图查询是什么样子的,我已经允许多个表和每个表的不同列名序列作为数组的数组传递给该函数:
参见单元测试:https://dbfiddle.uk/yBRur0Jr(邮政编码15)
注:如果数据量非常大,则使用过程可能更适合。
beq87vna2#
没有一种机制允许视图使用纯SQL忽略丢失的外部表。由于网络连接问题而无法访问的外部表与由于其所在的存储不可用而无法访问的表没有任何不同。默默地忽略无法访问的表似乎不合逻辑。人们如何知道数据丢失?由于表为空而缺少数据t等同于由于表格不可用而缺乏数据。
如果您坚持静默地忽略不可用的表,那么您可以创建表函数,在异常发生时返回查询外部表的结果或空结果集。然后您的视图可以使用这些函数的结果,而不是直接查询外部表。可以这样做并不意味着应该这样做。