Home Explore Blog CI



postgresql

74th chunk of `doc/src/sgml/plpgsql.sgml`
e27f2a023abb755736f0a6379a8cf3cdb2178f7dfc29d0dd0000000100000fa1
    v_domain varchar,
                                                        v_url varchar)
        RETURNS varchar AS '
      || quote_literal(func_body)
      || ' LANGUAGE plpgsql;' ;

    EXECUTE func_cmd;
END;
$func$ LANGUAGE plpgsql;
</programlisting>
     Notice how the body of the function is built separately and passed
     through <literal>quote_literal</literal> to double any quote marks in it.  This
     technique is needed because we cannot safely use dollar quoting for
     defining the new function: we do not know for sure what strings will
     be interpolated from the <structfield>referrer_key.key_string</structfield> field.
     (We are assuming here that <structfield>referrer_key.kind</structfield> can be
     trusted to always be <literal>host</literal>, <literal>domain</literal>, or
     <literal>url</literal>, but <structfield>referrer_key.key_string</structfield> might be
     anything, in particular it might contain dollar signs.) This function
     is actually an improvement on the Oracle original, because it will
     not generate broken code when <structfield>referrer_key.key_string</structfield> or
     <structfield>referrer_key.referrer_type</structfield> contain quote marks.
    </para>
   </example>

   <para>
    <xref linkend="plpgsql-porting-ex3"/> shows how to port a function
    with <literal>OUT</literal> parameters and string manipulation.
    <productname>PostgreSQL</productname> does not have a built-in
    <function>instr</function> function, but you can create one
    using a combination of other
    functions. In <xref linkend="plpgsql-porting-appendix"/> there is a
    <application>PL/pgSQL</application> implementation of
    <function>instr</function> that you can use to make your porting
    easier.
   </para>

   <example id="plpgsql-porting-ex3">
    <title>Porting a Procedure With String Manipulation and
    <literal>OUT</literal> Parameters from <application>PL/SQL</application> to
    <application>PL/pgSQL</application></title>

    <para>
     The following <productname>Oracle</productname> PL/SQL procedure is used
     to parse a URL and return several elements (host, path, and query).
    </para>

    <para>
     This is the Oracle version:
<programlisting>
CREATE OR REPLACE PROCEDURE cs_parse_url(
    v_url IN VARCHAR2,
    v_host OUT VARCHAR2,  -- This will be passed back
    v_path OUT VARCHAR2,  -- This one too
    v_query OUT VARCHAR2) -- And this one
IS
    a_pos1 INTEGER;
    a_pos2 INTEGER;
BEGIN
    v_host := NULL;
    v_path := NULL;
    v_query := NULL;
    a_pos1 := instr(v_url, '//');

    IF a_pos1 = 0 THEN
        RETURN;
    END IF;
    a_pos2 := instr(v_url, '/', a_pos1 + 2);
    IF a_pos2 = 0 THEN
        v_host := substr(v_url, a_pos1 + 2);
        v_path := '/';
        RETURN;
    END IF;

    v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
    a_pos1 := instr(v_url, '?', a_pos2 + 1);

    IF a_pos1 = 0 THEN
        v_path := substr(v_url, a_pos2);
        RETURN;
    END IF;

    v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
    v_query := substr(v_url, a_pos1 + 1);
END;
/
show errors;
</programlisting>
    </para>

    <para>
     Here is a possible translation into <application>PL/pgSQL</application>:
<programlisting>
CREATE OR REPLACE FUNCTION cs_parse_url(
    v_url IN VARCHAR,
    v_host OUT VARCHAR,  -- This will be passed back
    v_path OUT VARCHAR,  -- This one too
    v_query OUT VARCHAR) -- And this one
AS $$
DECLARE
    a_pos1 INTEGER;
    a_pos2 INTEGER;
BEGIN
    v_host := NULL;
    v_path := NULL;
    v_query := NULL;
    a_pos1 := instr(v_url, '//');

    IF a_pos1 = 0 THEN
        RETURN;
    END IF;
    a_pos2 := instr(v_url, '/', a_pos1 + 2);
    IF a_pos2 = 0 THEN
        v_host := substr(v_url, a_pos1 + 2);
        v_path := '/';
        RETURN;
    END IF;

    v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
    a_pos1 := instr(v_url, '?', a_pos2 + 1);

    IF a_pos1 = 0 THEN
        v_path := substr(v_url,

Title: Porting a Procedure With String Manipulation and OUT Parameters from PL/SQL to PL/pgSQL
Summary
This section focuses on porting a PL/SQL procedure to PL/pgSQL that parses a URL and returns its host, path, and query components using OUT parameters and string manipulation. It highlights the absence of a built-in instr function in PostgreSQL and suggests creating one using other functions. The example provides the original Oracle PL/SQL code and its corresponding PL/pgSQL translation, showcasing how to handle OUT parameters and string functions in the PostgreSQL environment.