PostgreSQL 函数从 URL 中提取 HTTP 查询参数

Tob*_*ias 1 postgresql plpgsql postgresql-9.3

我想从代表 URL 的字符串中提取查询参数,并且我想在存储函数中执行此操作(偶然没有我可以使用的标准函数?)。

在 Python 中,这将是:

from urlparse import urlparse, parse_qs
def extract_oid(url):
    """
    extract the 'oid' query argument

    (simplified, no error handling)

    >>> extract_oid('http://some.host/some/path?oid=abc123&other')
    'abc123'
    """
    return parse_qs(urlparse(url).query)['oid'][0]
Run Code Online (Sandbox Code Playgroud)

我目前的尝试plpgsql是:

CREATE OR REPLACE FUNCTION extract_oid (link text)
RETURNS text
AS $$
DECLARE
  pos1 integer := position('&oid=' in link);
  tail text := substring(link from pos1 + 1);
  endpos integer := position('&' in tail);
BEGIN
  if link is NULL or pos1 = 0 then
    RETURN NULL;
  ELSIF endpos = 0 then
    RETURN substring(tail from 5);
  ELSE
    RETURN substring(tail from 5 for endpos - 1);
  END IF;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

如果 是查询字符串中的最后一个参数并且至少有一个前任参数(否则我也oid需要识别),则此方法可以正常工作;?oid=但是,当有另一个时它会失败&跟随者时,它会失败。我想在这里保持安全......

该变量似乎有问题endpos

有人可以启发我吗?谢谢你!

我需要它与 PostgreSQL 9.3+ 一起使用。

编辑:

我发现我的逻辑错误(当然我需要减去5而不是1,愚蠢的我),但是在马的回答之后,我的函数看起来像这样:

CREATE OR REPLACE FUNCTION extract_oid (url text)
RETURNS text
AS $$
BEGIN
  RETURN split_part(substring(url from '[?&]oid=[^&]+'), '=', 2);
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

小智 5

除了在Python 函数中使用 Python 代码之外,我还会使用正则表达式:

split_part(substring(link from 'oid=\w+'), '=', 2)
Run Code Online (Sandbox Code Playgroud)

substring(link from 'oid=\w+')将返回oid=abc123,然后提取用作分隔符的split_part()第二个元素。=

with t (url) as (
  values 
    ('http://some.host/some/path?oid=abc123&other'), 
    ('http://some.host/some/path?other&oid=def456&foo=bar')
)
select split_part(substring(url from 'oid=\w+'), '=', 2)
from t;
Run Code Online (Sandbox Code Playgroud)

将返回:

split_part
----------
abc123    
def456    
Run Code Online (Sandbox Code Playgroud)

我认为这也应该适用于 9.3

  • 是的,谢谢!我将“from”表达式更改为“[?&]oid=[^&]+”以忽略“otherprefixoid”变量并允许非单词字符。 (2认同)