Home Explore Blog CI



postgresql

75th chunk of `doc/src/sgml/plpgsql.sgml`
586abdd2972e5be1730759d5223f45bba718ad4e93fcfef90000000100000fa0
 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, 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;
$$ LANGUAGE plpgsql;
</programlisting>

     This function could be used like this:
<programlisting>
SELECT * FROM cs_parse_url('http://foobar.com/query.cgi?baz');
</programlisting>
    </para>
   </example>

   <para>
    <xref linkend="plpgsql-porting-ex4"/> shows how to port a procedure
    that uses numerous features that are specific to Oracle.
   </para>

   <example id="plpgsql-porting-ex4">
    <title>Porting a Procedure from <application>PL/SQL</application> to <application>PL/pgSQL</application></title>

    <para>
     The Oracle version:

<programlisting>
CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS
    a_running_job_count INTEGER;
BEGIN
    LOCK TABLE cs_jobs IN EXCLUSIVE MODE;

    SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;

    IF a_running_job_count &gt; 0 THEN
        COMMIT; -- free lock
        raise_application_error(-20000,
                 'Unable to create a new job: a job is currently running.');
    END IF;

    DELETE FROM cs_active_job;
    INSERT INTO cs_active_job(job_id) VALUES (v_job_id);

    BEGIN
        INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now());
    EXCEPTION
        WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists
    END;
    COMMIT;
END;
/
show errors
</programlisting>
   </para>

   <para>
    This is how we could port this procedure to <application>PL/pgSQL</application>:

<programlisting>
CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id integer) AS $$
DECLARE
    a_running_job_count integer;
BEGIN
    LOCK TABLE cs_jobs IN EXCLUSIVE MODE;

    SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;

    IF a_running_job_count &gt; 0 THEN
        COMMIT; -- free lock
        RAISE EXCEPTION 'Unable to create a new job: a job is currently running'; -- <co id="co.plpgsql-porting-raise"/>
    END IF;

    DELETE FROM cs_active_job;
    INSERT INTO cs_active_job(job_id) VALUES (v_job_id);

    BEGIN
        INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now());
    EXCEPTION
        WHEN unique_violation THEN -- <co id="co.plpgsql-porting-exception"/>
            -- don't worry if it already exists
    END;
    COMMIT;
END;
$$ LANGUAGE plpgsql;
</programlisting>

    <calloutlist>
     <callout arearefs="co.plpgsql-porting-raise">
      <para>
       The syntax of <literal>RAISE</literal> is considerably different from
       Oracle's statement, although the basic case <literal>RAISE</literal>
       <replaceable class="parameter">exception_name</replaceable> works
       similarly.
      </para>
     </callout>
     <callout arearefs="co.plpgsql-porting-exception">
      <para>
       The exception names supported by <application>PL/pgSQL</application> are
       different from Oracle's.  The set of built-in exception names
    

Title: More Examples of Porting PL/SQL Procedures to PL/pgSQL
Summary
This section provides more examples of porting PL/SQL procedures to PL/pgSQL, including a procedure that uses URL parsing with OUT parameters, and another that involves locking tables, checking job counts, and handling exceptions. The examples highlight the differences in syntax and exception handling between Oracle's PL/SQL and PostgreSQL's PL/pgSQL, such as the use of RAISE EXCEPTION and different exception names like unique_violation.