27-1:
	CREATE OR REPLACE PROCEDURE dyn_ddl(string VARCHAR2) IS
	  c INTEGER;
	  ret INTEGER;
	BEGIN
	  c:=dbms_sql.open_cursor;
	  dbms_sql.parse(c,string,DBMS_SQL.NATIVE);
	  ret:=dbms_sql.execute(c);
	  dbms_sql.close_cursor(c);
	END;
	/
	exec scott.dyn_ddl('CREATE TABLE my(cola int)')
	exec scott.dyn_ddl('INSERT INTO scott.my VALUES(1)')
27-2:
	CREATE OR REPLACE PROCEDURE bulk_insert_emp(
	  empno_array DBMS_SQL.NUMBER_TABLE,
	  ename_array DBMS_SQL.VARCHAR2_TABLE,
	  sal_array DBMS_SQL.NUMBER_TABLE)
	IS
	  c INTEGER;
	  ret INTEGER;
	  stmt VARCHAR2(100);
	BEGIN
	  stmt:='INSERT INTO emp (empno,ename,sal) '||
	    'VALUES(:num_array,:name_array,:salary_array)';
	  c := DBMS_SQL.OPEN_CURSOR;
	  DBMS_SQL.PARSE(c, stmt, DBMS_SQL.NATIVE);
	  DBMS_SQL.BIND_ARRAY(c, ':num_array', empno_array);
	  DBMS_SQL.BIND_ARRAY(c, ':name_array', ename_array);
	  DBMS_SQL.BIND_ARRAY(c, ':salary_array', sal_array);
	  ret := DBMS_SQL.EXECUTE(c);
	  DBMS_SQL.CLOSE_CURSOR(c);
	EXCEPTION
	  WHEN OTHERS THEN
	    DBMS_SQL.CLOSE_CURSOR(c);
	END;
	/
	DECLARE
	  empno_array DBMS_SQL.NUMBER_TABLE;
	  ename_array DBMS_SQL.VARCHAR2_TABLE;
	  sal_array DBMS_SQL.NUMBER_TABLE;
	BEGIN
	  FOR i in 0..9 LOOP
	    empno_array(i) := 1000 + i;
	    ename_array(i) := 'name'||i;
	    sal_array(i):=1000+10*i;
	  END LOOP;
	  bulk_insert_emp(empno_array,ename_array,sal_array);
	END;
	/
27-3:
	CREATE OR REPLACE PROCEDURE bulk_update_emp(
	  empno_array DBMS_SQL.NUMBER_TABLE,
	  sal_array DBMS_SQL.NUMBER_TABLE)
	IS
	  c INTEGER;
	  ret INTEGER;
	  stmt VARCHAR2(100);
	BEGIN
	  stmt:='UPDATE emp SET sal=:salary_array '||'WHERE empno=:num_array';
	  c := DBMS_SQL.OPEN_CURSOR;
	  DBMS_SQL.PARSE(c, stmt, DBMS_SQL.NATIVE);
	  DBMS_SQL.BIND_ARRAY(c, ':salary_array', sal_array);
	  DBMS_SQL.BIND_ARRAY(c, ':num_array', empno_array);
	  ret := DBMS_SQL.EXECUTE(c);
	  DBMS_SQL.CLOSE_CURSOR(c);
	EXCEPTION
	  WHEN OTHERS THEN
	    DBMS_SQL.CLOSE_CURSOR(c);
	END;
	/
	DECLARE
	  empno_array DBMS_SQL.NUMBER_TABLE;
	  sal_array DBMS_SQL.NUMBER_TABLE;
	BEGIN
	  FOR i in 0..9 LOOP
	    empno_array(i) := 1000 + i;
	    sal_array(i):=1000+100*i;
	  END LOOP;
	  bulk_update_emp(empno_array,sal_array);
	END;
	/
27-4:
	CREATE OR REPLACE PROCEDURE bulk_delete_emp
	(empno_array DBMS_SQL.NUMBER_TABLE)
	IS
	  c INTEGER;
	  ret INTEGER;
	  stmt VARCHAR2(100);
	BEGIN
	  stmt:='DELETE emp WHERE empno=:num_array';
	  c := DBMS_SQL.OPEN_CURSOR;
	  DBMS_SQL.PARSE(c, stmt, DBMS_SQL.NATIVE);
	  DBMS_SQL.BIND_ARRAY(c, ':num_array', empno_array);
	  ret := DBMS_SQL.EXECUTE(c);
	  DBMS_SQL.CLOSE_CURSOR(c);
	EXCEPTION
	  WHEN OTHERS THEN
	    DBMS_SQL.CLOSE_CURSOR(c);
	END;
	/
	DECLARE
	  empno_array DBMS_SQL.NUMBER_TABLE;
	BEGIN
	  FOR i in 0..9 LOOP
	    empno_array(i) := 1000 + i;
	  END LOOP;
	  bulk_delete_emp(empno_array);
	END;
	/
27-5:
	CREATE OR REPLACE PROCEDURE bulk_query_emp(
	  dno NUMBER,
	  empno_array OUT DBMS_SQL.NUMBER_TABLE,
	  ename_array OUT DBMS_SQL.VARCHAR2_TABLE,
	  sal_array OUT DBMS_SQL.NUMBER_TABLE)
	IS
	  c INTEGER;
	  ret INTEGER;
	  stmt VARCHAR2(100);
	BEGIN
	  stmt:='SELECT empno,ename,sal FROM emp WHERE deptno=:no';
	  c := DBMS_SQL.OPEN_CURSOR;
	  DBMS_SQL.PARSE(c, stmt, DBMS_SQL.NATIVE);
	  DBMS_SQL.BIND_VARIABLE(c,':no',dno);
	  DBMS_SQL.DEFINE_ARRAY(c, 1, empno_array, 100, 1);
	  DBMS_SQL.DEFINE_ARRAY(c, 2, ename_array, 100, 1);
	  DBMS_SQL.DEFINE_ARRAY(c, 3, sal_array, 100, 1);
	  ret := DBMS_SQL.EXECUTE(c);
	  ret := DBMS_SQL.FETCH_ROWS(c);
	  DBMS_SQL.COLUMN_VALUE(c, 1, empno_array);
	  DBMS_SQL.COLUMN_VALUE(c, 2, ename_array);
	  DBMS_SQL.COLUMN_VALUE(c, 3, sal_array);
	  DBMS_SQL.CLOSE_CURSOR(c);
	END;
	/
	DECLARE
	  empno_array DBMS_SQL.NUMBER_TABLE;
	  ename_array DBMS_SQL.VARCHAR2_TABLE;
	  sal_array DBMS_SQL.NUMBER_TABLE;
	BEGIN
	  bulk_query_emp(&dno,empno_array,ename_array,sal_array);
	  FOR i IN 1..empno_array.COUNT LOOP
	    dbms_output.put_line(empno_array(i)||'  '||ename_array(i)||'  '||sal_array(i));
	  END LOOP;
	END;
	/





