home *** CD-ROM | disk | FTP | other *** search
/ Winzipper / Winzipper_ISO.iso / programming / oracle7 7.2 / DB / UTIL72 / PRVTDESC.SQL < prev    next >
Encoding:
Text File  |  1995-05-09  |  8.2 KB  |  195 lines

  1. rem 
  2. rem $Header: prvtdesc.sql 7020200.1 95/02/15 18:29:37 cli Generic<base> $ 
  3. rem 
  4. Rem
  5. Rem    NAME
  6. Rem      prvtdesc.sql - describe stored procedures and functions
  7. Rem    DESCRIPTION
  8. Rem      These are private functions to be released in PL/SQL binary form.
  9. Rem      Given a stored procedure, return a description of the 
  10. Rem      arguments required to call that procedure.
  11. Rem    RETURNS
  12. Rem 
  13. Rem    NOTES
  14. Rem      The procedural option is needed to use this facility.
  15. Rem      
  16. Rem    MODIFIED   (MM/DD/YY)
  17. Rem     rtaranto   12/13/94 -  merge changes from branch 1.1.710.2
  18. Rem     rtaranto   12/13/94 -  Handle remote object lookup errors correctly
  19. Rem     adowning   03/29/94 -  merge changes from branch 1.1.710.1
  20. Rem     adowning   02/04/94 -  Creation
  21. Rem     adowning   02/02/94 -  split file into public / private binary files
  22. Rem     rkooi      11/26/92 -  change some comment 
  23. Rem     rkooi      11/21/92 -  check for top level functions 
  24. Rem     rkooi      11/17/92 -  get rid of database name 
  25. Rem     rkooi      11/12/92 -  change name res stuff 
  26. Rem     mmoore     11/01/92 -  Creation 
  27.  
  28. REM ********************************************************************
  29. REM THIS PACKAGE MUST NOT BE MODIFIED BY THE CUSTOMER.  DOING SO
  30. REM COULD CAUSE INTERNAL ERRORS AND SECURITY VIOLATIONS IN THE
  31. REM RDBMS.  SPECIFICALLY, THE PSD* ROUTINES MUST NOT BE CALLED
  32. REM DIRECTLY BY ANY CLIENT AND MUST REMAIN PRIVATE TO THE PACKAGE BODY.
  33. REM ********************************************************************
  34.  
  35. create or replace package body dbms_describe is 
  36.     procedure describe_procedure (object_name in varchar2,
  37.         reserved1 in varchar2, reserved2 in varchar2,
  38.         overload out number_table, position out number_table,
  39.         level out number_table, argument_name out varchar2_table,
  40.         datatype out number_table, default_value out number_table,
  41.         in_out out number_table, length out number_table,
  42.         precision out number_table, scale out number_table,
  43.         radix out number_table, spare out number_table) is
  44.  
  45.       NOT_EXIST_OR_NO_PRIV exception;
  46.       pragma EXCEPTION_INIT(NOT_EXIST_OR_NO_PRIV, -6564);
  47.       PROC_NOT_IN_PKG exception;
  48.       pragma EXCEPTION_INIT(PROC_NOT_IN_PKG, -6563);
  49.  
  50.       cursor get_procedure_args(obj_number binary_integer) is 
  51.         select argument, overload#, position, type,
  52.                nvl(default#,0) default#, nvl(in_out,0) in_out,
  53.                nvl(level#,0) level#, nvl(length,0) length, 
  54.                nvl(precision,0) precision, nvl(scale,0) scale, 
  55.                nvl(radix,0) radix
  56.         from argument$ 
  57.         where obj# = obj_number
  58.         order by obj#,procedure$,overload#,sequence#;
  59.  
  60.       cursor get_package_args(obj_number binary_integer,proc_name varchar2) is 
  61.         select argument, overload#, position, type,
  62.                nvl(default#,0) default#, nvl(in_out,0) in_out,
  63.                nvl(level#,0) level#, nvl(length,0) length, 
  64.                nvl(precision,0) precision, nvl(scale,0) scale, 
  65.                nvl(radix,0) radix
  66.         from argument$
  67.         where obj# = obj_number and procedure$ = proc_name
  68.         order by obj#,procedure$,overload#,sequence#;
  69.  
  70.       sch    varchar2(30);
  71.       part1  varchar2(30);
  72.       part2  varchar2(30);
  73.       db     varchar2(128);
  74.       typ    number;
  75.       objno  number;
  76.       i      binary_integer := 0;
  77.       found  boolean := FALSE;
  78.       status number;
  79.       nm     varchar2(200);      -- tmp place to hold fully expanded name
  80.                                  -- for error messages
  81.       
  82.     begin 
  83.         
  84.       begin
  85.         dbms_utility.name_resolve(object_name, 1, sch, part1, part2, db, typ,
  86.           objno);
  87.       exception 
  88.         when not_exist_or_no_priv or proc_not_in_pkg then
  89.           raise;
  90.         when others then
  91.           raise_application_error(-20004, 'syntax error attempting to parse "'
  92.             || object_name || '"', keeperrorstack => TRUE);
  93.       end;
  94.  
  95.       if (objno = -1 and part2 is not null) then
  96.         raise_application_error(-20002, 'ORU-10033: object ' || object_name ||
  97.           ' is remote, cannot describe a procedure in a remote package');
  98.       end if;
  99.  
  100.       nm := sch;
  101.       if (part1 is not null) then nm := nm || '.' || part1; end if;
  102.       if (part2 is not null) then nm := nm || '.' || part2; end if;
  103.       if (db is not null)    then nm := nm || '@' || db;    end if;
  104.  
  105.       -- if the translated object is local then query the local dictionary
  106.       if (db is null) then -- an equivalent test would 'typ != 5' (!synonym)
  107.       
  108.         if (part1 is not null and part2 is null) then
  109.           raise_application_error(-20000,
  110.             'ORU-10035: cannot describe a package (' || object_name ||
  111.             '); only a procedure within a package');
  112.         end if;
  113.  
  114.         -- see if object is valid
  115.         select status into status from obj$ where obj#=objno;
  116.         if status != 1 then
  117.           raise_application_error(-20003, 'ORU-10036: object ' ||
  118.              object_name || ' is invalid and cannot be described');
  119.         end if;
  120.  
  121.         -- if part1 is a top level procedure or function
  122.         if (typ = 7 or typ = 8) then
  123.           
  124.           -- load the procedure's arguments 
  125.           for tab_rec in get_procedure_args(objno) loop
  126.             i := i + 1;
  127.             argument_name(i) := tab_rec.argument;
  128.             overload(i)      := tab_rec.overload#;
  129.             position(i)      := tab_rec.position;
  130.             /* program interface does not support type 29 (SB4) yet so
  131.                don't give impression that it does, map to DTYINT instead.
  132.                We can get rid of this mapping later when the program
  133.                interface is enhanced.  For compatibility, this mapping
  134.                could be controlled by the future use of one of the
  135.                'reserved' argments */
  136.             if tab_rec.type = 29 then     -- internal sb4
  137.               datatype(i)    := 3;        -- external native int
  138.             elsif tab_rec.type = 69 then  -- internal rowid
  139.               datatype(i)    := 11;       -- external rowid
  140.             else
  141.               datatype(i)    := tab_rec.type;
  142.             end if;
  143.             default_value(i) := tab_rec.default#;
  144.             level(i)         := tab_rec.level#;
  145.             in_out(i)        := tab_rec.in_out;
  146.             length(i)        := tab_rec.length;
  147.             precision(i)     := tab_rec.precision;
  148.             scale(i)         := tab_rec.scale;
  149.             radix(i)         := tab_rec.radix;
  150.             spare(i)         := 0;
  151.           end loop;
  152.         else 
  153.           -- get the procedure's arguments from within the package
  154.           for tab_rec in get_package_args(objno, part2) loop
  155.             i := i + 1;
  156.             argument_name(i) := tab_rec.argument;
  157.             overload(i)      := tab_rec.overload#;
  158.             position(i)      := tab_rec.position;
  159.             /* see comment above */
  160.             if tab_rec.type = 29 then    -- internal sb4
  161.               datatype(i)    := 3;       -- external native int
  162.             elsif tab_rec.type = 69 then -- internal rowid
  163.               datatype(i)    := 11;      -- external rowid
  164.             else
  165.               datatype(i)    := tab_rec.type;
  166.             end if;
  167.             default_value(i) := tab_rec.default#;
  168.             in_out(i)        := tab_rec.in_out;
  169.             level(i)         := tab_rec.level#;
  170.             length(i)        := tab_rec.length;
  171.             precision(i)     := tab_rec.precision;
  172.             scale(i)         := tab_rec.scale;
  173.             radix(i)         := tab_rec.radix;
  174.             spare(i)         := 0;
  175.           end loop;
  176.  
  177.           -- if no rows returned then the package did not have the procedure
  178.           if i = 0 then
  179.             raise_application_error(-20001, 
  180.               'ORU-10032: procedure ' || part2 || ' within package ' ||
  181.           part1 || ' does not exist');
  182.           end if;
  183.         end if;
  184.       else
  185.  
  186.         -- need to forward the describe call to the remote database, but
  187.         -- don't support that yet.
  188.         raise_application_error(-20002, 
  189.             'ORU-10033: object ' || object_name ||
  190.             ' is remote, cannot describe; expanded name: ' || nm);
  191.       end if;
  192.    end;
  193. end;
  194. /  
  195.