next up previous
Next: PL/SQL Cartridge: OWA_UTIL package Up: No Title Previous: Executing queries

Example

A package, called dsql, is defined which contains two procedures:

-- p20.sql
CREATE OR REPLACE PACKAGE dsql AS
  TYPE dd_rec_type IS RECORD (
    table_name varchar2(30),
    column_name varchar2(30),
    data_type  varchar2(9));
  TYPE dd_table_type IS TABLE OF dd_rec_type 
       INDEX BY BINARY_INTEGER;
  TYPE string1024_table IS TABLE OF varchar2(1024) 
       INDEX BY BINARY_INTEGER;
  TYPE string9_table IS TABLE OF varchar2(9) 
       INDEX BY BINARY_INTEGER;
  TYPE number_table IS TABLE OF number
       INDEX BY BINARY_INTEGER;

PROCEDURE get_columns(startch IN char,
                      dd_table OUT dd_table_type,
                      n OUT number);

procedure get_query_results(query_string IN varchar2,
                            ncols IN number,
                            column_types IN string9_table,
                            result OUT string1024_table,
                            nrows OUT number); 

END dsql;
/
show errors

CREATE OR REPLACE PACKAGE BODY dsql AS

PROCEDURE get_columns(startch in char,
                      dd_table OUT dd_table_type,
                      n OUT number) AS
handle Integer;
dbms_return Integer;
tablename varchar(30);
colname varchar(30);
datatype varchar(9);
counter integer := 0;

begin

  handle := DBMS_SQL.OPEN_CURSOR;
  DBMS_SQL.PARSE(handle,
    'select distinct table_name,column_name,data_type ' ||
    'from   user_tab_columns '                          ||
    'where  table_name like '''                         || 
    startch                                        || 
    '%'''                                          ||
    'order by table_name,column_name', DBMS_SQL.V7);

  DBMS_SQL.DEFINE_COLUMN(handle, 1, tablename, 30);
  DBMS_SQL.DEFINE_COLUMN(handle, 2, colname, 30);
  DBMS_SQL.DEFINE_COLUMN(handle, 3, datatype, 9);

  dbms_return := DBMS_SQL.EXECUTE(handle);

  counter := 0;
  loop
    if DBMS_SQL.FETCH_ROWS(handle) = 0 then
      exit;
    else
      DBMS_SQL.COLUMN_VALUE(handle, 1, tablename);
      DBMS_SQL.COLUMN_VALUE(handle, 2, colname);
      DBMS_SQL.COLUMN_VALUE(handle, 3, datatype);
 
      counter := counter + 1;
      dd_table(counter).table_name := tablename;
      dd_table(counter).column_name := colname;
      dd_table(counter).data_type := datatype;
    end if;
  end loop;
  n := counter;
  DBMS_SQL.CLOSE_CURSOR(handle);

EXCEPTION
  WHEN OTHERS THEN
    DBMS_SQL.CLOSE_CURSOR(handle);
    n := -1;
END get_columns;

procedure get_query_results(query_string IN varchar2,
                            ncols IN number,
                            column_types IN string9_table,
                            result OUT string1024_table,
                            nrows OUT number) AS

y1 string1024_table;
y2 number_table;
counter Integer;
i Integer;
handle Integer;
dbms_return Integer;
temp string1024_table;

BEGIN

  for i in 1 .. ncols loop
    y1(i) := '';
    y2(i) := 0;
  end loop;

  counter := 0;
  handle := DBMS_SQL.OPEN_CURSOR;
  DBMS_SQL.PARSE(handle,query_string,DBMS_SQL.V7);

  for i in 1 .. ncols loop
    if ((column_types(i) = 'VARCHAR2') or
        (column_types(i) = 'CHAR')) then
      DBMS_SQL.DEFINE_COLUMN(handle, i, y1(i) , 300);
    else
      DBMS_SQL.DEFINE_COLUMN(handle, i, y2(i));
    end if;
  end loop;

  dbms_return := DBMS_SQL.EXECUTE(handle);

  loop
     if DBMS_SQL.FETCH_ROWS(handle) = 0 then
       exit;
     else
       for i in 1 .. ncols loop
         if ((column_types(i) = 'VARCHAR2') or
             (column_types(i) = 'CHAR')) then
           DBMS_SQL.COLUMN_VALUE(handle, i, y1(i));
         else
           DBMS_SQL.COLUMN_VALUE(handle, i, y2(i));
         end if;
       end loop; 
       counter := counter + 1;
       temp(counter) := '';

       for i in 1 .. ncols loop
         if ((column_types(i) = 'VARCHAR2') or
             (column_types(i) = 'CHAR')) then
           temp(counter) := temp(counter) || 
                            rtrim(y1(i)) || '|';
         else
           temp(counter) := temp(counter) || 
                            rtrim(y2(i)) || '|';
         end if;
       end loop;
   end if;
  end loop;

  nrows := counter;
  result := temp;
  DBMS_SQL.CLOSE_CURSOR(handle);

  EXCEPTION
    WHEN OTHERS THEN
      DBMS_SQL.CLOSE_CURSOR(handle);
      nrows := -1;
END get_query_results;
end dsql;
/
show errors

The following package, called dsql_driver contains two procedures to drive the two procedures in the dsql package.

-- p21.sql 
CREATE OR REPLACE PACKAGE dsql_driver AS
procedure drive_get_columns(startch IN char);
procedure drive_get_query_results(
    query_string IN varchar2,
    ncols IN number,
    column_types IN dsql.string9_table);
END dsql_driver;
/

CREATE OR REPLACE PACKAGE BODY dsql_driver AS
procedure drive_get_columns(startch IN char) AS
  dd_table dsql.dd_table_type;
  i binary_integer;
  n number;
  prev varchar2(30);
  newentry boolean;
BEGIN
  dsql.get_columns(startch,dd_table,n);
  dbms_output.put_line('N =  ' || n);
  
  dbms_output.put_line('Tables Starting with ' || 
                        startch);
  dbms_output.put_line('------------------------');

  prev := '';
  newentry := false;
  for i in 1 .. dd_table.count loop
    if (i = 1) then
      dbms_output.put(dd_table(i).table_name || '(');
      prev := dd_table(i).table_name;
    elsif (prev != dd_table(i).table_name) then
      dbms_output.put_line(');');
      dbms_output.put(dd_table(i).table_name || '(');
      prev := dd_table(i).table_name;
      newentry := false;
    end if;
    if (newentry) then
      dbms_output.put(', ');
    end if;
    newentry := true;
    dbms_output.put(dd_table(i).column_name || ':');
    dbms_output.put(dd_table(i).data_type);
  end loop;  
  dbms_output.put_line(');');
END;

procedure drive_get_query_results
    (query_string IN varchar2,
     ncols IN number,
     column_types IN dsql.string9_table) AS
result dsql.string1024_table;
nrows number;
i binary_integer;

BEGIN
  dsql.get_query_results(query_string,ncols,column_types,
                         result,nrows);
  for i in 1 .. nrows loop
    dbms_output.put_line(result(i));
  end loop;
END;

END dsql_driver;
/
show errors

The following anonymous PL/SQL block calls the driver procedure for the get_query_results procedure.

-- p22.sql
DECLARE
 query_string varchar2(256);
 ncols number;
 column_types dsql.string9_table;
BEGIN
  query_string := 'select cno,cname,city ' ||
                  'from customers,zipcodes ' ||
                  'where customers.zip = zipcodes.zip';
  ncols := 3;
  column_types(1) := 'NUMBER';
  column_types(2) := 'VARCHAR2';
  column_types(3) := 'VARCHAR2';

  dsql_driver.drive_get_query_results(query_string,
                                      ncols,
                                      column_types);
END;
/

The following is a sample SQL*PLUS session to illustrate the above example.

SQL> execute display_table('customers');
1111 Charles 123 Main St. 67226 316-636-5555
2222 Bertram 237 Ash Avenue 67226 316-689-5555
3333 Barbara 111 Inwood St. 60606 316-111-1234

PL/SQL procedure successfully completed.

SQL> execute display_table('abcd');
NOT A VALID TABLE NAME

PL/SQL procedure successfully completed.

SQL> start p22
1111|Charles|Wichita|
2222|Bertram|Wichita|
3333|Barbara|Fort Dodge|

PL/SQL procedure successfully completed.

SQL>


next up previous
Next: PL/SQL Cartridge: OWA_UTIL package Up: No Title Previous: Executing queries
Dr. Raj Sunderraman
7/8/1998