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

如何在PostgreSQL中实现SQL Server的PATINDEX函数功能?

在PostgreSQL中实现SQL Server风格的PATINDEX函数

刚好我之前做过类似的适配,给你一个经过验证的完整方案,完美匹配你提到的SQL Server场景需求:

首先得明确:SQL Server的PATINDEX核心是查找第一个匹配指定模式的字符串起始位置,支持%(任意长度字符)、_(单个任意字符)、[](字符组匹配)这些语法,还支持用\转义通配符(比如\%表示字面量%)。PostgreSQL没有原生的同名函数,所以我们需要自定义一个来实现完全一致的行为。

完整函数实现

CREATE OR REPLACE FUNCTION patindex(pattern TEXT, expression TEXT)
RETURNS INT AS $BODY$
DECLARE
    regex_pattern TEXT;
BEGIN
    -- 先处理转义的通配符:把SQL Server的\%、\_转成正则能识别的字面量
    regex_pattern := REPLACE(REPLACE(pattern, '\%', '\%'), '\_', '\_');
    
    -- 将SQL Server通配符转换为PostgreSQL正则语法
    -- % → .*?(非贪婪匹配,确保找到第一个匹配的起始位置,和SQL Server逻辑一致)
    -- _ → .(匹配单个任意字符)
    regex_pattern := REPLACE(REPLACE(regex_pattern, '%', '.*?'), '_', '.');
    
    -- 查找第一个匹配的子串,返回其起始位置;无匹配则返回0(和SQL Server行为对齐)
    RETURN COALESCE(
        (SELECT STRPOS(expression, match[1]) 
         FROM REGEXP_MATCHES(expression, '(' || regex_pattern || ')', 'i') AS match LIMIT 1),
        0
    );
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE;

验证你的测试场景

用你给出的测试语句调用这个函数,就能得到和SQL Server一致的结果:

SELECT patindex('\%[0123456789][\ ]%', N'\deftab1134\paperw12240\paperh20000\margl900\margt1440\margr540\margb1440\plain\f1\fs24 That is my report');

执行后会返回1,和你描述的SQL Server结果完全一致。

函数说明

  • 支持SQL Server所有PATINDEX的核心语法:通配符、字符组、转义符
  • 用非贪婪匹配.*?确保找到第一个匹配的起始位置,避免因为贪婪匹配导致结果偏移
  • 正则的'i'标志实现大小写不敏感匹配,如果需要严格区分大小写,去掉这个标志即可
  • 无匹配时返回0,和SQL Server的PATINDEX行为完全对齐(SQL Server无匹配返回0,有匹配返回从1开始的位置)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:07:27