You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java调用PostgreSQL函数时,如何用参数匹配所有ctv.value值?

问题描述

我编写了如下Java方法用于调用PostgreSQL函数:

public void cleanupCustomFields(String keyField, String keyFieldValue, String[] fieldsToCleanup)
            throws ServiceWareException {
        Connection conn = null;
        CallableStatement cleanupFields = null;

        try {
            conn = getConnection();

            cleanupFields = conn.prepareCall("{call cleanup_custom_tags(?, ?, ?)}");
            cleanupFields.setString(1, keyField);
            cleanupFields.setString(2, keyFieldValue);
            cleanupFields.setArray(3, conn.createArrayOf("varchar", fieldsToCleanup));
            cleanupFields.execute();
        } catch (SQLException ex) {
            throw new ServiceWareException(Messages.DATABASE_GENERAL_FAILURE, ex);
        } finally {
            closeConnection(conn, null, cleanupFields);
        }
    }

对应的PostgreSQL函数代码如下:

CREATE OR REPLACE FUNCTION public.cleanup_custom_tags(
    _tag_name character varying,
    _tag_value character varying,
    _tags_list character varying[])
    RETURNS void
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE SECURITY DEFINER PARALLEL UNSAFE
AS $BODY$
DECLARE
tag_id_list int[];
BEGIN
SELECT ARRAY_AGG(id) INTO tag_id_list FROM tbl_custom_tags WHERE tag_name = ANY(_tags_list);

DELETE  
FROM    tbl_custom_tag_values
WHERE   tag_id = ANY(tag_id_list) AND
    entity_id IN    (SELECT s.id
            FROM    tbl_servers s INNER JOIN
                tbl_custom_tag_values ctv ON s.id = ctv.entity_id INNER JOIN
                tbl_custom_tags ct ON ct.id = ctv.tag_id
            WHERE   ct.tag_name = _tag_name AND ctv.value = _tag_value);
END; 
$BODY$;

我希望给变量keyFieldValue(对应PG函数中的_tag_value)设置一个值,使其能匹配ctv.value中的所有内容(类似正则表达式.*的效果),但查阅文档后未能成功实现,请问需要使用什么语法?

解决方案

当前PostgreSQL函数中用ctv.value = _tag_value做精确匹配,要实现匹配所有内容的效果,推荐以下两种方式:

方式1:通过特殊标记触发全匹配逻辑

指定一个特殊值(比如'*'),当传入的_tag_value等于该值时,跳过ctv.value的匹配条件,直接匹配所有内容:

CREATE OR REPLACE FUNCTION public.cleanup_custom_tags(
    _tag_name character varying,
    _tag_value character varying,
    _tags_list character varying[])
    RETURNS void
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE SECURITY DEFINER PARALLEL UNSAFE
AS $BODY$
DECLARE
tag_id_list int[];
BEGIN
SELECT ARRAY_AGG(id) INTO tag_id_list FROM tbl_custom_tags WHERE tag_name = ANY(_tags_list);

DELETE  
FROM    tbl_custom_tag_values
WHERE   tag_id = ANY(tag_id_list) AND
    entity_id IN    (SELECT s.id
            FROM    tbl_servers s INNER JOIN
                tbl_custom_tag_values ctv ON s.id = ctv.entity_id INNER JOIN
                tbl_custom_tags ct ON ct.id = ctv.tag_id
            WHERE   ct.tag_name = _tag_name 
            -- 新增逻辑:如果_tag_value为'*'则匹配所有,否则精确匹配
            AND (_tag_value = '*' OR ctv.value = _tag_value));
END; 
$BODY$;

使用时,在Java代码中给keyFieldValue赋值为"*"即可实现全匹配。这种方式性能最优,还能保留ctv.value字段的索引利用率。

方式2:使用正则匹配(全量场景不推荐)

PostgreSQL支持用~操作符做正则匹配,当传入的_tag_value为'.*'时,就能匹配所有ctv.value内容:

-- 修改子查询中的条件部分
WHERE   ct.tag_name = _tag_name AND ctv.value ~ _tag_value

但这种方式会增加计算开销,且无法利用ctv.value上的索引(如果存在),仅适合需要灵活正则规则的场景,全量匹配不建议使用。

内容的提问来源于stack exchange,提问作者Liran_T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 13:18:27