Как я могу имитировать функцию php urldecode в postgresql? - PullRequest
3 голосов
/ 20 июня 2011

У меня есть столбец URL, закодированный с помощью urlencode в php. Я хочу сделать такой выбор SELECT some_mix_of_functions (...) AS декодированный из таблицы

Замена не является хорошим решением, потому что мне придется добавить все декодирование вручную. Любое другое решение, чтобы получить желаемый результат?

Ответы [ 2 ]

10 голосов
/ 13 декабря 2011

Да, вы можете:

CREATE OR REPLACE FUNCTION decode_url_part(p varchar) RETURNS varchar AS $$
SELECT convert_from(CAST(E'\\x' || string_agg(CASE WHEN length(r.m[1]) = 1 THEN encode(convert_to(r.m[1], 'SQL_ASCII'), 'hex') ELSE substring(r.m[1] from 2 for 2) END, '') AS bytea), 'UTF8')
FROM regexp_matches($1, '%[0-9a-f][0-9a-f]|.', 'gi') AS r(m);
$$ LANGUAGE SQL IMMUTABLE STRICT;

Это создает функцию decode_url_part, тогда вы можете использовать ее так:

SELECT decode_url_part('your%20urlencoded%20string')

Или вы можете просто использовать сочетание функций и подзапросов из тела вышеуказанной функции.

Это не обрабатывает символы '+' (представляющие пробелы), но я думаю, добавить это довольно легко (если вам это когда-нибудь понадобится).

Также предполагается, что для символов, отличных от ascii, используется кодировка utf-8, но вы можете заменить «UTF8» на собственную кодировку, если хотите.

Следует отметить, что приведенный выше код использует недокументированную функцию postgresql, а именно то, что результаты функции regexp_matches обрабатываются в том порядке, в котором они встречаются в исходной строке (что естественно, но не указано в документах).

Как отмечает Пабло Санта-Крус, string_agg - это агрегатная функция PostgreSQL 9.0. Эквивалентный код ниже не использует его (надеюсь, он работает для 8.x):

SELECT convert_from(CAST(E'\\x' || array_to_string(ARRAY(
    SELECT CASE WHEN length(r.m[1]) = 1 THEN encode(convert_to(r.m[1], 'SQL_ASCII'), 'hex') ELSE substring(r.m[1] from 2 for 2) END
    FROM regexp_matches($1, '%[0-9a-f][0-9a-f]|.', 'gi') AS r(m)
), '') AS bytea), 'UTF8');
0 голосов
/ 20 июня 2011

Не из коробки. Но вы можете создать функцию pl / perl, которая оборачивает эквивалент perl. (Или функция pl / php ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...