是否可以仅选择列(AD_CLIENT_ID
)包含特定数值(1000000
)的表?
我有850个表可供选择,每个表都有此列,但并非所有列都包含1000000。
答案 0 :(得分:2)
嗯..
答案 1 :(得分:1)
您可以使用执行动态SQL的plpgsql函数获取表的列表,循环遍历目录中的结果。考虑以下演示,在PostgreSQL 9.1上进行测试,但至少应该使用8.4版本甚至更早版本:
CREATE OR REPLACE FUNCTION f_tbl_with_value(numeric)
RETURNS SETOF text AS
$BODY$
DECLARE
_tbl text;
BEGIN
FOR _tbl IN
SELECT DISTINCT quote_ident(n.nspname) || '.' || quote_ident(c.relname)
FROM pg_catalog.pg_attribute a
JOIN pg_catalog.pg_class c ON c.oid = a.attrelid
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE a.attname = 'ad_client_id'
AND a.attisdropped = FALSE -- column hasn't been dropped
AND n.nspname = 'myschema' -- search only this schema
AND c.relkind = 'r' -- only real tables
LOOP
RETURN QUERY EXECUTE '
SELECT ''' || _tbl || '''::text
WHERE EXISTS (
SELECT *
FROM ' || _tbl || '
WHERE ad_client_id = $1
)'
USING $1;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;
呼叫:
SELECT * FROM x.f_tbl_with_value(100000)
结果是列ad_client_id
所在的表名列表,其中包含至少一行中的参数值。
我使用PostgreSQL目录。您可以像在评论中演示的那样使用SQL标准信息架构。但这速度要慢很多,只有在你想保持代码可移植性时才有用。由于这个plpgsql函数无法移植到其他数据库系统,我使用更快的PostgreSQL目录表。
请注意我如何使用纯SQL来检索表名,但dynamic SQL来查询它们。
请注意我如何在架构和表名上使用quote_ident()
来防止SQL注入,并在需要时自动保留混合大小写标识符。
我使用小写字符串'ad_client_id'
作为列名。或者你真的需要大写,因为你在创建它时双引"AD_CLIENT_ID"
? (我通常建议仅使用小写标识符。More about that in the manual.)