Những gì bạn đang cố gắng làm khó có thể thực hiện được toàn bộ.
Tạo SQL động
Đầu tiên, đây là những gì bạn có thể do:một hàm plpgsql tạo SQL cho một truy vấn như vậy:
CREATE OR REPLACE FUNCTION f_union_common_col_sql(text, text)
RETURNS text
AS $function$
DECLARE
_cols text;
BEGIN
_cols := string_agg(attname, ', ')
FROM (
SELECT a.attname
FROM pg_attribute a
WHERE a.attrelid = $1::regclass::oid
AND a.attnum >= 1
INTERSECT
SELECT a.attname
FROM pg_attribute a
WHERE a.attrelid = $2::regclass::oid
AND a.attnum >= 1
) x;
RETURN 'SELECT ' || _cols || '
FROM ' || quote_ident($1) || '
UNION
SELECT ' || _cols || '
FROM ' || quote_ident($1);
END;
$function$ LANGUAGE plpgsql;
COMMENT ON FUNCTION f_union_common_col_sql(text, text) IS 'Create SQL to query all visible columns that two tables have in common.
# Without duplicates. Use UNION ALL if you want to include duplicates.
# Depends on visibility dicatated by search_path
$1 .. table1: optionally schema-qualified, case sensitive!
$2 .. table2: optionally schema-qualified, case sensitive!';
Gọi:
SELECT f_union_common_col_sql('myschema1.tbl1', 'myschema2.tbl2');
Cung cấp cho bạn truy vấn hoàn chỉnh. Thực thi nó trong cuộc gọi thứ hai.
Bạn có thể tìm thấy hầu hết mọi thứ tôi đã sử dụng ở đây trong hướng dẫn sử dụng các hàm plpgsql .
hàm tổng hợp string_agg()
đã được giới thiệu với PostgreSQL 9.0. Trong các phiên bản cũ hơn, bạn sẽ:array_to_string(array_agg(attname), ', ')
.
Thực thi SQL động?
Tiếp theo, đây là những gì bạn khó có thể làm:
CREATE OR REPLACE FUNCTION f_union_common_col(text, text)
RETURNS SETOF record AS
$BODY$
DECLARE
_cols text;
BEGIN
_cols := string_agg(attname, ', ')
FROM (
SELECT a.attname
FROM pg_attribute a
WHERE a.attrelid = $1::regclass::oid
AND a.attnum >= 1
INTERSECT
SELECT a.attname
FROM pg_attribute a
WHERE a.attrelid = $2::regclass::oid
AND a.attnum >= 1
) x;
RETURN QUERY EXECUTE '
SELECT ' || _cols || '
FROM quote_ident($1)
UNION
SELECT ' || _cols || '
FROM quote_ident($2)';
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
COMMENT ON FUNCTION f_union_common_col(text, text) IS 'Query all visible columns that two tables have in common.
# Without duplicates. Use UNION ALL if you want to include duplicates.
# Depends on visibility dicatated by search_path
# !BUT! you need to specify a column definition list for every call. So, hardly useful.
$1 .. table1 (optionally schema-qualified)
$2 .. table1 (optionally schema-qualified)';
Một lệnh gọi hàm yêu cầu bạn chỉ định danh sách các cột mục tiêu. vì vậy điều này hầu như không hữu ích chút nào:
SELECT * from f_union_common_col('myschema1.tbl1', 'myschema2.tbl2')
ERROR: a column definition list is required for functions returning "record"
Không có cách nào dễ dàng để giải quyết vấn đề này. Bạn sẽ phải tạo động một hàm hoặc ít nhất là một kiểu phức tạp. Đây là nơi tôi dừng lại.