首页 > 解决方案 > PostgreSQL:仅匹配整个单词的模式

问题描述

我有一个包含数百个 SQL 查询的“查询”表,我试图过滤掉只能在我正在使用的数据库上执行的查询。因为其中一些查询引用了只存在于另一个数据库中的表,所以只有一小部分可以成功执行。

到目前为止,我的查询如下所示:

SELECT rr.name AS query_name,
    (
        SELECT string_agg(it.table_name::character varying, ', ' ORDER BY it.table_name)
        FROM information_schema.tables it
        WHERE rr.config ->> 'queries' SIMILAR TO ('%' || it.table_name || '%')
    )       AS related_tables

FROM queries rr

它确实工作正常,除了我提供的模式不是过滤掉边缘情况的最佳选择。

假设我在旧数据库中有一个名为“customers_archived”的表,在新数据库中不存在,而在旧数据库和新数据库中都有一个名为“customers”的表。

现在,对于我编写的查询,引擎认为,“嗯,我有一个名为 customers 的表,因此任何包含单词 customers 的查询都必须是有效的”,但是引擎是错误的,因为它还选择了包含“customers_archived”表的查询该数据库中不存在。

所以我试图只匹配整个单词,但我无法让它工作,因为就我而言,\ 字符在 PGSQL 中不起作用。我怎样才能让这个查询来做我想要实现的目标?

标签: sqlstringpostgresql

解决方案


除了构建完整的 PostgreSQL SQL 解析器之外,没有完全可靠的方法可以找到查询引用的表。对于初学者,名称可以出现在字符串文字中,或者查询可以是

DO $$BEGIN EXECUTE 'SELECT * FROM my' || 'table'; END;$$;

但我认为如果你确保在比赛中你的名字周围有非单词字符,你会更好:

WHERE rr.config ->> 'queries' ~ '\y' || it.table_name || '\y'

推荐阅读