Rok*_*oki 5 postgresql stored-procedures urlencode plpgsql
PostgreSQL/plpgsql中有没有与javascripts encodeURI相同的函数/存储过程?
这是什么意思?Javascript有一个方便的内置函数来编码任何类型的URL:
encodeURI(url) - >返回已编码的url
例如:
encodeURI('http://hu.wikipedia.org/wiki/São_Paulo')- >返回一个String"http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo"
我寻找完全一样的.
我不想单独编码每个参数.我不希望像javascript encodeURIComponent这样的函数不一样.上面的例子产生了不同的输出
encodeURIComponent('http://hu.wikipedia.org/wiki/São_Paulo')
Run Code Online (Sandbox Code Playgroud)
- > "http%3A%2F%2Fhu.wikipedia.org%2Fwiki%2FS%C3%A3o_Paulo"
它编码整个字符串而不仅仅是路径部分.所以这不是我想要的.我需要一个plpgsql函数,它导致javascript函数encodeURI的等效输出.
谢谢!
vye*_*rov 13
慢和低效,考虑做C这个功能的版本:
CREATE OR REPLACE FUNCTION urlencode(in_str text, OUT _result text)
STRICT IMMUTABLE AS $urlencode$
DECLARE
_i int4;
_temp varchar;
_ascii int4;
BEGIN
_result = '';
FOR _i IN 1 .. length(in_str) LOOP
_temp := substr(in_str, _i, 1);
IF _temp ~ '[0-9a-zA-Z:/@._?#-]+' THEN
_result := _result || _temp;
ELSE
_ascii := ascii(_temp);
IF _ascii > x'07ff'::int4 THEN
RAISE EXCEPTION 'Won''t deal with 3 (or more) byte sequences.';
END IF;
IF _ascii <= x'07f'::int4 THEN
_temp := '%'||to_hex(_ascii);
ELSE
_temp := '%'||to_hex((_ascii & x'03f'::int4)+x'80'::int4);
_ascii := _ascii >> 6;
_temp := '%'||to_hex((_ascii & x'01f'::int4)+x'c0'::int4)
||_temp;
END IF;
_result := _result || upper(_temp);
END IF;
END LOOP;
RETURN ;
END;
$urlencode$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
结果:
# select urlencode('http://hu.wikipedia.org/wiki/São_Paulo');
-[ RECORD 1 ]------------------------------------------
urlencode | http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo
Run Code Online (Sandbox Code Playgroud)
这是一个非常古老的线程,但令人惊讶的是,之前发布的解决方案似乎都不符合相关的RFC 3986。所以这里有两个 PostgreSQL 函数encode_uri(如果你想编码一个完整的URI)和encode_uri_component(如果你只想编码URI的一个组成部分,例如查询参数的键或值),它们结合了Nick的错误解决方案,ElDiabolo的注释,以及Kev 从相关线程 到单个有效的仅 SQL 解决方案的部分解决方案。
工作原理:首先,将字符串分解为单个字符,然后对每个多字节字符和每个不允许的字符进行十六进制编码。
编码 URI 组件:
create or replace function encode_uri_component(text) returns text as $$
select string_agg(
case
when bytes > 1 or c !~ '[0-9a-zA-Z_.!~*''()-]+' then
regexp_replace(encode(convert_to(c, 'utf-8')::bytea, 'hex'), '(..)', E'%\\1', 'g')
else
c
end,
''
)
from (
select c, octet_length(c) bytes
from regexp_split_to_table($1, '') c
) q;
$$ language sql immutable strict;
Run Code Online (Sandbox Code Playgroud)
编码完整 URI:
create or replace function encode_uri(text) returns text as $$
select string_agg(
case
when bytes > 1 or c !~ '[0-9a-zA-Z_.!~*''();,/?:@&=+$#-]+' then
regexp_replace(encode(convert_to(c, 'utf-8')::bytea, 'hex'), '(..)', E'%\\1', 'g')
else
c
end,
''
)
from (
select c, octet_length(c) bytes
from regexp_split_to_table($1, '') c
) q;
$$ language sql immutable strict;
Run Code Online (Sandbox Code Playgroud)
用PL/V8 ......作弊?
create function encode_uri(text) returns text language plv8 strict immutable as $$
return encodeURI($1);
$$;
Run Code Online (Sandbox Code Playgroud)
今天我遇到了“不会处理 3 个(或更多)字节序列”。对于韩语字符,虽然我已经使用@vyegorov的答案很长一段时间了,一年多了,需要更改它只是转储带有“%”前缀的bytea十六进制字符串。
\n\nCREATE OR REPLACE FUNCTION urlencode(in_str text, OUT _result text)\n STRICT IMMUTABLE AS $urlencode$\nDECLARE\n _i int4;\n _temp varchar;\n _hex varchar;\n _ascii int4;\nBEGIN\n _result = \'\';\n FOR _i IN 1 .. length(in_str) LOOP\n _temp := substr(in_str, _i, 1);\n IF _temp ~ \'[0-9a-zA-Z:/@._?#-]+\' THEN\n _result := _result || _temp;\n ELSE\n _hex := encode(_temp::bytea, \'hex\');\n _temp := \'\';\n WHILE LENGTH(_hex) > 0 LOOP\n _temp := _temp || \'%\' || SUBSTRING(_hex, 1, 2);\n _hex := SUBSTRING(_hex, 3, 999);\n END LOOP;\n _result := _result || upper(_temp);\n END IF;\n END LOOP;\n RETURN ;\nEND;\n$urlencode$ LANGUAGE plpgsql;\nRun Code Online (Sandbox Code Playgroud)\n\n例子,
\n\nSELECT urlencode(\'a\') UNION ALL --> "a"\nSELECT urlencode(\'\xc3\x80\') UNION ALL --> "%C3%80"\nSELECT urlencode(\'\xc4\x80\') UNION ALL --> "%C4%80"\nSELECT urlencode(\'\xc9\x99\') UNION ALL --> "%C9%99"\nSELECT urlencode(\'\xce\xb1\') UNION ALL --> "%CE%B1"\nSELECT urlencode(\'\xea\xb0\x80\') UNION ALL --> "%EA%B0%80"\nSELECT urlencode(\'\xe4\xb8\x8a\') UNION ALL --> "%E4%B8%8A"\nSELECT urlencode(\'\xe3\x81\x84\') --> "%E3%81%84"\nRun Code Online (Sandbox Code Playgroud)\n
我写了解决这个问题的PostgreSQL 扩展url_enocode
postgres=# select url_encode('http://hu.wikipedia.org/wiki/São_Paulo');
url_encode
???????????????????????????????????????????????????????
http%3A%2F%2Fhu.wikipedia.org%2Fwiki%2FS%C3%A3o_Paulo
Run Code Online (Sandbox Code Playgroud)
或者
postgres=# select uri_encode('http://hu.wikipedia.org/wiki/São_Paulo');
uri_encode
---------------------------------------------
http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5846 次 |
| 最近记录: |