2017-11-07 7 views
0

Ich möchte ein Abfrageargument aus einer Zeichenfolge extrahieren, die eine URL darstellt, und ich möchte es in einer gespeicherten Funktion tun (es gibt nicht zufällig einige Standardfunktion könnte ich verwenden?).PostgreSQL-Funktion zum Extrahieren eines HTTP-Abfragearguments von einer URL

In Python, dies wäre:

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] 

Mein aktueller Versuch in plpgsql ist:

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; 

Dies funktioniert gut, wenn die oid das letzte Argument in der Abfragezeichenfolge ist und zumindest ein Vorgänger (sonst müsste ich auch erkennen); es schlägt jedoch fehl, wenn ein weiterer & folgt. Ich möchte hier sefe sein ...

Etwas scheint mit der Variablen endpos falsch zu sein.

Kann mir bitte jemand aufklären? Vielen Dank!

Ich brauche das mit PostgreSQL 9.3+ zu arbeiten.

Edit:

ich meine logischen Fehler gefunden (natürlich 5 musste ich eher subtrahieren als 1, albern mich), aber nach der Antwort des Pferdes, sieht meine Funktion wie folgt aus:

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

Antwort

1

Apart Ihren Python-Code in einem Python function verwenden, würde ich einen regulären Ausdruck für diesen Einsatz:

split_part(substring(link from 'oid=\w+'), '=', 2) 

substring(link from 'oid=\w+') gibt oid=abc123 zurück und split_part() extrahiert dann das zweite Element unter Verwendung von = als Trennzeichen.

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; 

zurückkehren wird:

split_part 
---------- 
abc123  
def456  

denke ich, dass auch auf 9.3 funktionieren sollte

+1

Ja, danke! Ich habe den Ausdruck 'from' in' '[? &] Oid = [^ &] +' geändert, um "andere Präfixoid" -Vars zu ignorieren und auch Nicht-Wort-Zeichen zuzulassen. – Tobias

Verwandte Themen