Name

SQL-19: Encapsulate dynamic SQL parsing to improve error detection and cleanup.

Synopsis

Dynamic SQL is tricky; you generally glue together different chunks of text (with the concatenation operator) to form what you hope is a valid SQL or PL/SQL statement. Either through programmer error or user error, you can end up with a bad chunk of SQL, resulting in a parse error.

To identify and fix these errors, you should create your own parsing “engine” on top of DBMS_SQL.PARSE and the NDS statements. This program traps and displays error information, and cleans up any cursors.

Example

This technique is most crucial for DBMS_SQL. Don’t ever call DBMS_SQL.PARSE directly in your program. Instead, call your own parse encapsulator. Why would you bother to do this? Consider the following block of code. It leaves a DBMS_SQL cursor unclosed and unclosable; you need to be able to reference the dyncur variable in the call to DBMS_SQL.CLOSE_CURSOR, but that variable is erased once the exception is propagated:

DECLARE
    dyncur PLS_INTEGER := DBMS_SQL.open_cursor;
BEGIN
    -- Whoops, forget the FROM clause!
    DBMS_SQL.parse (
       dyncur, 'select * dual', DBMS_SQL.native);
END;

Here’s a very simple example of an encapsulation for DBMS_SQL.PARSE:

CREATE OR REPLACE FUNCTION open_and_parse ( dynsql_in IN VARCHAR2, dbms_mode_in IN INTEGER := NULL) RETURN INTEGER IS dyncur INTEGER; BEGIN dyncur := DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE (dyncur, dynsql_in, NVL (dbms_mode_in, DBMS_SQL.NATIVE)); RETURN dyncur; EXCEPTION ...

Get Oracle PL/SQL Best Practices now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.