home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / db / rdbms71 / prvtdesc.sql < prev    next >
Encoding:
Text File  |  1994-08-07  |  7.7 KB  |  188 lines

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