Example 1
The following sample procedure is passed a SQL statement, which it then parses and executes:
CREATE OR REPLACE PROCEDURE exec(STRING IN varchar2) AS cursor_name INTEGER; ret INTEGER; BEGIN cursor_name := DBMS_SQL.OPEN_CURSOR; --DDL statements are executed by the parse call, which --performs the implied commit DBMS_SQL.PARSE(cursor_name, string, DBMS_SQL.V7); ret := DBMS_SQL.EXECUTE(cursor_name); DBMS_SQL.CLOSE_CURSOR(cursor_name); END;
Creating such a procedure allows you to perform the following operations:
exec('create table acct(c1 integer)');
You could even call this procedure remotely, as shown in the following example. This allows you to perform remote DDL.
exec@hq.com('CREATE TABLE acct(c1 INTEGER)');
Example 2
The following sample procedure is passed the names of a source and a destination table, and copies the rows from the source table to the destination table. This sample procedure assumes that both the source and destination tables have the following columns:
ID of type NUMBER NAME of type VARCHAR2(30) BIRTHDATE of type DATE
This procedure does not specifically require the use of dynamic SQL; however, it illustrates the concepts of this package.
CREATE OR REPLACE PROCEDURE copy(source IN VARCHAR2, destination IN VARCHAR2) is -- This procedure copies rows from a given source table to a -- given destination table assuming that both source and -- destination tables have the following columns: -- - ID of type NUMBER, -- - NAME of type VARCHAR2(30), -- - BIRTHDATE of type DATE. id NUMBER; name VARCHAR2(30); birthdate DATE; source_cursor INTEGER; destination_cursor INTEGER; ignore INTEGER; BEGIN -- prepare a cursor to select from the source table source_cursor := dbms_sql.open_cursor; DBMS_SQL.PARSE(source_cursor, 'SELECT id, name, birthdate FROM ' || source, DBMS_SQL.V7); DBMS_SQL.DEFINE_COLUMN(source_cursor, 1, id); DBMS_SQL.DEFINE_COLUMN(source_cursor, 2, name, 30); DBMS_SQL.DEFINE_COLUMN(source_cursor, 3, birthdate); ignore := DBMS_SQL.EXECUTE(source_cursor); -- prepare a cursor to insert into the destination table destination_cursor := DBMS_SQL.OPEN_CURSOR; DBMS_SQL.PARSE(destination_cursor, 'INSERT INTO ' || destination || ' VALUES (:id, :name, :birthdate)', DBMS_SQL.V7); -- fetch a row from the source table and -- insert it into the destination table LOOP IF DBMS_SQL.FETCH_ROWS(source_cursor)>0 THEN -- get column values of the row DBMS_SQL.COLUMN_VALUE(source_cursor, 1, id); DBMS_SQL.COLUMN_VALUE(source_cursor, 2, name); DBMS_SQL.COLUMN_VALUE(source_cursor, 3, birthdate); -- bind the row into the cursor that inserts into the -- destination table -- You could alter this example to require the use of -- dynamic SQL by inserting an if condition before the -- bind. DBMS_SQL.BIND_VARIABLE(destination_cursor, 'id', id); DBMS_SQL.BIND_VARIABLE(destination_cursor, 'name', name); DBMS_SQL.BIND_VARIABLE(destination_cursor, 'birhtdate', birthdate); ignore := DBMS_SQL.EXECUTE(destination_cursor); ELSE -- no more row to copy EXIT; END IF; END LOOP; -- commit and close all cursors COMMIT; DBMS_SQL.CLOSE_CURSOR(source_cursor); DBMS_SQL.CLOSE_CURSOR(destination_cursor); EXCEPTION WHEN OTHERS THEN IF DBMS_SQL.IS_OPEN(source_cursor) THEN DBMS_SQL.CLOSE_CURSOR(source_cursor); END IF; IF DBMS_SQL.IS_OPEN(destination_cursor) THEN DBMS_SQL.CLOSE_CURSOR(destination_cursor); END IF; RAISE; END;