7

javascripts encodeURI と同じ関数/ストアド プロシージャが PostgreSQL/plpgsql にありますか?

どういう意味ですか?Javascript には、あらゆる種類の URL をエンコードするための便利な組み込み関数があります。

encodeURI(url) -> エンコードされた URL を返します

例: encodeURI('http://hu.wikipedia.org/wiki/São_Paulo')-> 次の文字列を返します。"http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo"

私はまったく同じを探しています。

各パラメーターを個別にエンコードしたくありません。同じではない javascript encodeURIComponent のような関数は必要ありません。上記の例では、次のように異なる出力が得られます

encodeURIComponent('http://hu.wikipedia.org/wiki/São_Paulo')

->"http%3A%2F%2Fhu.wikipedia.org%2Fwiki%2FS%C3%A3o_Paulo"

パス部分だけでなく、文字列全体をエンコードします。だから、これは私が探しているものではありません。javascript関数encodeURIと同等の出力をもたらすplpgsql関数が必要です。

ありがとう!

4

8 に答える 8

15

遅くて非効率的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;

結果:

# select urlencode('http://hu.wikipedia.org/wiki/São_Paulo');
-[ RECORD 1 ]------------------------------------------
urlencode | http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo
于 2012-04-25T18:58:43.527 に答える
6

この問題を解決するPostgreSQL 拡張機能url_encodeを作成しました。

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

また

postgres=# select uri_encode('http://hu.wikipedia.org/wiki/São_Paulo');
               uri_encode                  
---------------------------------------------
http://hu.wikipedia.org/wiki/S%C3%A3o_Paulo
于 2012-04-29T14:21:51.320 に答える
6

PL/V8 で...ごまかし?

create function encode_uri(text) returns text language plv8 strict immutable as $$
  return encodeURI($1);
$$;
于 2014-09-24T22:35:15.107 に答える
5

今日、「3 つ (またはそれ以上) のバイト シーケンスを処理できません」というメッセージに遭遇しました。韓国語の文字については、@vyegorov の回答を 1 年以上もかなり長い間使用してきましたが、変更する必要があるのは、「%」を前に付けたバイト 16 進文字列をダンプするだけです。

CREATE OR REPLACE FUNCTION urlencode(in_str text, OUT _result text)
    STRICT IMMUTABLE AS $urlencode$
DECLARE
    _i      int4;
    _temp   varchar;
    _hex    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
            _hex := encode(_temp::bytea, 'hex');
            _temp := '';
            WHILE LENGTH(_hex) > 0 LOOP
                _temp := _temp || '%' || SUBSTRING(_hex, 1, 2);
                _hex := SUBSTRING(_hex, 3, 999);
            END LOOP;
            _result := _result || upper(_temp);
        END IF;
    END LOOP;
    RETURN ;
END;
$urlencode$ LANGUAGE plpgsql;

例、

SELECT urlencode('a') UNION ALL  --> "a"
SELECT urlencode('À') UNION ALL  --> "%C3%80"
SELECT urlencode('Ā') UNION ALL  --> "%C4%80"
SELECT urlencode('ə') UNION ALL  --> "%C9%99"
SELECT urlencode('α') UNION ALL  --> "%CE%B1"
SELECT urlencode('가') UNION ALL --> "%EA%B0%80"
SELECT urlencode('上') UNION ALL --> "%E4%B8%8A"
SELECT urlencode('い')           --> "%E3%81%84"
于 2016-11-23T11:10:09.673 に答える
2

tsohr と Nick の回答における ::bytea の使用法は間違っています。SELECT '\'::bytea を実行して理由を確認してください。

どちらの場合も、convert_to(x, 'utf-8') で目的の結果が得られます。

于 2019-07-01T19:28:14.863 に答える