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

  1. rem 
  2. rem $Header: prvtutil.sql 7010300.1 94/02/24 18:23:48 snataraj Generic<base> $ 
  3. rem 
  4. Rem
  5. Rem    NAME
  6. Rem      prvtutil.sql - packages of various utility procedures
  7. Rem    DESCRIPTION
  8. Rem      These are private functions to be released in PL/SQL binary form.
  9. Rem      This file contains various packages:
  10. Rem         dbms_transaction    - transaction commands
  11. Rem         dbms_session    - alter session commands
  12. Rem         dbms_ddl        - ddl commands
  13. Rem         dbms_utility    - helpful utilities
  14. Rem    RETURNS
  15. Rem 
  16. Rem    NOTES
  17. Rem      The procedural option is needed to use these facilities.
  18. Rem
  19. Rem      All of the packages below run with the privileges of calling user,
  20. Rem      rather than the package owner ('sys').
  21. Rem
  22. Rem      Procedure 'dbms_ddl.alter_compile' and 'dbms_ddl.analyze_object
  23. Rem      commit the current transaction, perform the compilation, and 
  24. Rem      then commit again.
  25. Rem 
  26. Rem      The dbms_utility package is run-as-caller (psdicd.c) only for
  27. Rem      its name_resolve, compile_schema and analyze_schema
  28. Rem      procedures.  This package is not run-as-caller
  29. Rem      w.r.t. SQL (psdpgi.c) so that the SQL works correctly (runs as
  30. Rem      SYS).  The privileges are checked via dbms_ddl.
  31. Rem
  32. Rem    MODIFIED   (MM/DD/YY)
  33. Rem     lchen      02/11/94 -  sync with plb
  34. Rem     wmaimone   02/07/94 -  add set close_cached_open_cursors to dbms_sessio
  35. Rem     dsdaniel   02/04/94 -  dbms_util.port_string icd
  36. Rem     adowning   02/04/94 -  Branch_for_patch
  37. Rem     adowning   02/04/94 -  Creation
  38. Rem     adowning   02/02/94 -  split file into public / private binary files
  39. Rem     rjenkins   10/28/93 -  make comma_to_table more consistent
  40. Rem     rjenkins   10/12/93 -  adding comma_to_table
  41. Rem     rjenkins   09/03/93 -  adding name_parse
  42. Rem     hjakobss   07/15/93 -  bug 170473
  43. Rem     hjakobss   07/13/93 -  bug 169577
  44. Rem     dsdaniel   03/12/93 -  local_tid, step_id functions for replication  
  45. Rem     mmoore     01/11/93 -  merge changes from branch 1.37.312.1 
  46. Rem     mmoore     01/05/93 - #(145287) add another exception for discrete mode
  47. Rem     mmoore     12/11/92 -  disable set_role in stored procs 
  48. Rem     rkooi      11/24/92 -  fixes per Peter 
  49. Rem     rkooi      11/21/92 -  get rid of error argument to name_resolve 
  50. Rem     tpystyne   11/20/92 -  fix compile_all and analyze_schema 
  51. Rem     rkooi      11/16/92 -  fix set_label 
  52. Rem     rkooi      11/16/92 -  fix comments 
  53. Rem     rkooi      11/13/92 -  add name_res procedure 
  54. Rem     tpystyne   11/07/92 -  make analyze parameters optional 
  55. Rem     mmoore     11/04/92 -  add new analyze options 
  56. Rem     ghallmar   11/03/92 -  add dbms_transaction.purge_mixed 
  57. Rem     rkooi      10/30/92 -  get rid of caller_id and unique_stmt_id 
  58. Rem     rkooi      10/26/92 -  owner -> schema for SQL2 
  59. Rem     rkooi      10/25/92 -  bug 135880 
  60. Rem     mmoore     10/13/92 - #(131686) change messages 2074,4092,0034 
  61. Rem     rkooi      10/02/92 -  compile_all fix 
  62. Rem     mmoore     10/02/92 -  change pls_integer to binary_integer 
  63. Rem     tpystyne   10/01/92 -  fix Bob's mistakes 
  64. Rem     tpystyne   09/28/92 -  disallow commit/rollback force in rpc and trigge
  65. Rem     mmoore     09/25/92 - #(130566) don't allow set_nls or set_role in trig
  66. Rem     tpystyne   09/23/92 -  rename analyze to analyze_object 
  67. Rem     rkooi      08/24/92 -  handle delimited id's in alter_compile 
  68. Rem     tpystyne   08/06/92 -  add analyze_schema 
  69. Rem     epeeler    07/29/92 -  add function to get time 
  70. Rem     rkooi      06/25/92 -  workaround pl/sql bug with 'in' in SQL
  71. Rem     rkooi      06/03/92 -  add 'get unique session id' 
  72. Rem     jcohen     05/28/92 -  add = to alter session set label 
  73. Rem     jloaiza    05/12/92 -  add discrete 
  74. Rem     rkooi      04/22/92 -  put in checks for execute_sql for triggs, stored
  75. Rem     mmoore     04/14/92 -  move begin_oltp to package transaction 
  76. Rem     rkooi      04/06/92 -  merge changes from branch 1.4.300.1 
  77. Rem     rkooi      04/01/92 -  Creation - split/recombined from other files
  78. Rem     mroberts   02/21/92 -  call alter_compile, not sql_ddl 
  79. Rem     rkooi      02/06/92 -  testing 
  80. Rem     rkooi      02/03/92 -  compilation errors 
  81. Rem     rkooi      01/16/92 -  Creation 
  82.  
  83. REM ********************************************************************
  84. REM THESE PACKAGES MUST NOT BE MODIFIED BY THE CUSTOMER.  DOING SO
  85. REM COULD CAUSE INTERNAL ERRORS AND SECURITY VIOLATIONS IN THE
  86. REM RDBMS.  SPECIFICALLY, THE PSD* AND EXECUTE_SQL ROUTINES MUST NOT BE
  87. REM CALLED DIRECTLY BY ANY CLIENT AND MUST REMAIN PRIVATE TO THE PACKAGE BODY.
  88. REM ********************************************************************
  89.  
  90. create or replace package body dbms_transaction is
  91.   -- internal icd:  perform DDL statement
  92.   procedure execute_sql(coord_sess_ok binary_integer, forms_ok binary_integer,
  93.       trigger_ok binary_integer, procedure_ok binary_integer, stmt varchar2, 
  94.       error_hint varchar2);
  95.     pragma interface (C, execute_sql);                     -- 6 (see psdicd.c)
  96.  
  97.   -- internal icd: get transaction id
  98.   function ltid_icd(create_txn binary_integer) return varchar2;
  99.     pragma interface (c, ltid_icd);                        -- 7 (see psdicd.c)
  100.  
  101.   -- internal icd: get step id
  102.   function step_icd return number;
  103.     pragma interface (c, step_icd);                        -- 8 (see psdicd.c)
  104.  
  105.   procedure commit_force(xid varchar2, scn varchar2 default null) is
  106.   begin
  107.     if scn is NULL then
  108.       execute_sql(0, 0, 0, 1, 'commit force ''' || xid || '''', 'COMMIT');
  109.     else 
  110.       execute_sql(0, 0, 0, 1, 'commit force ''' || xid || ''' ''' ||
  111.         scn || '''', 'COMMIT');
  112.     end if;
  113.   end;
  114.  
  115.   procedure rollback_force(xid varchar2) is
  116.   begin
  117.     execute_sql(0, 0, 0, 1, 'rollback force ''' || xid || '''', 'ROLLBACK');
  118.   end;
  119.  
  120.   procedure advise_commit is
  121.   begin
  122.     execute_sql(1, 1, 1, 1, 'alter session advise commit', 'ADVISE COMMIT');
  123.   end;
  124.  
  125.   procedure advise_rollback is
  126.   begin
  127.     execute_sql(1, 1, 1, 1, 'alter session advise rollback', 
  128.                  'ADVISE ROLLBACK');
  129.   end;
  130.  
  131.   procedure advise_nothing is
  132.   begin
  133.     execute_sql(1, 1, 1, 1, 'alter session advise nothing','ADVISE NOTHING');
  134.   end;
  135.  
  136.   procedure commit_comment(cmnt varchar2) is
  137.   begin
  138.     execute_sql(0, 0, 0, 1, 'commit comment ' || '''' || cmnt || '''', 
  139.                 'COMMIT');
  140.   end;
  141.  
  142.   procedure read_only is
  143.   begin
  144.     execute_sql(0, 1, 0, 1, 'set transaction read only', 'SET TRANSACTION');
  145.   end;
  146.  
  147.   procedure read_write is
  148.   begin
  149.     execute_sql(0, 1, 0, 1, 'set transaction read write', 'SET TRANSACTION');
  150.   end;
  151.  
  152.   procedure use_rollback_segment(rb_name varchar2) is
  153.   begin
  154.     execute_sql(0, 1, 0, 1, 'set transaction use rollback segment ' || rb_name,
  155.        'SET TRANSACTION');
  156.   end;
  157.  
  158.   procedure purge_mixed(xid varchar2) is
  159.     transaction_not_found exception;
  160.   begin
  161.     use_rollback_segment('SYSTEM');
  162.     delete from sys.pending_trans$ where status = 'D' and local_tran_id = xid;
  163.     if sql%rowcount = 1 then
  164.       delete from sys.pending_sessions$ where local_tran_id = xid;
  165.       delete from sys.pending_sub_sessions$ where local_tran_id = xid;
  166.     else
  167.       raise transaction_not_found;
  168.     end if;
  169.   end;
  170.  
  171.   FUNCTION local_transaction_id(create_transaction BOOLEAN := FALSE)
  172.     RETURN VARCHAR2 is
  173.   begin
  174.     if create_transaction then
  175.       return(ltid_icd(1));
  176.     else
  177.       return(ltid_icd(0));
  178.     end if;
  179.   end;
  180.  
  181.   FUNCTION step_id RETURN NUMBER is
  182.   begin
  183.    return(step_icd);
  184.   end;
  185.  
  186. end;
  187. /
  188.  
  189. create or replace package body dbms_session is
  190.   -- internal icd:  perform DDL statement
  191.   procedure execute_sql(coord_sess_ok binary_integer, forms_ok binary_integer,
  192.       trigger_ok binary_integer, procedure_ok binary_integer, stmt varchar2, 
  193.       error_hint varchar2);
  194.     pragma interface (C, execute_sql);                      -- 1 (see psdicd.c)
  195.  
  196.   -- deinstantiate all pkgs in this session
  197.   procedure psddin;                        -- 2 (see psdicd.c)
  198.     pragma interface (C, psddin);
  199.  
  200.   -- get an id that is unique for all sessions in this database
  201.   function psduis return varchar2;                -- 3 (see psdicd.c)
  202.     pragma interface (C, psduis);
  203.  
  204.   -- is given role enabled?
  205.   function psdire(rolename varchar2) return binary_integer; -- 4 (see psdicd.c)
  206.     pragma interface (C, psdire);
  207.  
  208.   procedure set_role(role_cmd varchar2) is
  209.   begin
  210.     execute_sql(1, 1, 0, 0, 'set role ' || role_cmd, 'SET ROLE');
  211.   end;
  212.  
  213.   procedure set_sql_trace(sql_trace boolean) is
  214.   begin
  215.     if sql_trace then
  216.       execute_sql(1, 1, 1, 1, 'alter session set sql_trace true', 
  217.         'SET SQL_TRACE');
  218.     else
  219.       execute_sql(1, 1, 1, 1, 'alter session set sql_trace false',
  220.         'SET SQL_TRACE');
  221.     end if;
  222.   end;
  223.  
  224.   procedure set_nls(param varchar2, value varchar2) is
  225.     ddl_error exception;
  226.   begin
  227.     /* prevent sneaking in other 'alter session set' commands */
  228.     if substr(upper(param),1,4) <> 'NLS_' 
  229.         or length(value) > 20 then
  230.       raise ddl_error;
  231.     end if;
  232.     execute_sql(0, 1, 0, 1, 'alter session set ' || param || ' = ' || value,
  233.        'SET NLS');
  234.   end;
  235.  
  236.   procedure close_database_link(dblink varchar2) is
  237.   begin
  238.     execute_sql(1, 1, 1, 1, 'alter session close database link ' || dblink,
  239.       'CLOSE DATABASE LINK');
  240.   end;
  241.  
  242.   procedure set_label(lbl varchar2) is
  243.   begin
  244.     if upper(lbl) = 'DBHIGH' or upper(lbl) = 'DBLOW' then
  245.       execute_sql(0, 1, 1, 1, 'alter session set label = ' || lbl, 'SET LABEL');
  246.     else
  247.       execute_sql(0, 1, 1, 1, 'alter session set label = ''' || lbl || '''',
  248.         'SET LABEL');
  249.     end if;
  250.   end;
  251.  
  252.   procedure set_mls_label_format(fmt varchar2) is
  253.   begin
  254.     execute_sql(0, 1, 1, 1,
  255.       'alter session set mls_label_format = ''' || fmt || '''', 
  256.       'SET MLS LABEL FORMAT');
  257.   end;
  258.  
  259.   procedure reset_package is
  260.   begin
  261.     psddin;
  262.   end;
  263.  
  264.   function unique_session_id return varchar2 is
  265.   begin
  266.     return psduis;
  267.   end;
  268.  
  269.   function is_role_enabled(rolename varchar2) return boolean is
  270.   begin
  271.     if psdire(rolename) = 1 then
  272.       return TRUE;
  273.     else
  274.       return FALSE;
  275.     end if;
  276.   end;
  277.  
  278.   procedure set_close_cached_open_cursors(close_cursors boolean) is
  279.   begin
  280.     if close_cursors then
  281.       execute_sql(1, 1, 1, 1, 
  282.     'alter session set close_cached_open_cursors = true',
  283.         'SET CLOSE_CACHED_OPEN_CURSORS'); 
  284.    else
  285.       execute_sql(1, 1, 1, 1, 
  286.     'alter session set close_cached_open_cursors = false',
  287.         'SET CLOSE_CACHED_OPEN_CURSORS');
  288.     end if;
  289.   end;
  290.  
  291. end;
  292. /
  293.  
  294. create or replace package body dbms_ddl is
  295.   NOT_EXIST0 exception;
  296.   pragma EXCEPTION_INIT(NOT_EXIST0, -942);
  297.   NOT_EXIST1 exception;
  298.   pragma EXCEPTION_INIT(NOT_EXIST1, -4042);
  299.   NOT_EXIST2 exception;
  300.   pragma EXCEPTION_INIT(NOT_EXIST2, -4043);
  301.   NOT_EXIST3 exception;
  302.   pragma EXCEPTION_INIT(NOT_EXIST3, -6564);
  303.   NOT_EXIST4 exception;
  304.   pragma EXCEPTION_INIT(NOT_EXIST4, -943);
  305.   NOT_EXIST5 exception;
  306.   pragma EXCEPTION_INIT(NOT_EXIST5, -1418);
  307.   NO_PRIV    exception;
  308.   pragma EXCEPTION_INIT(NO_PRIV, -1031);
  309.  
  310.   -- internal icd:  perform DDL statement
  311.   procedure execute_sql(coord_sess_ok binary_integer, forms_ok binary_integer,
  312.       trigger_ok binary_integer, procedure_ok binary_integer, stmt varchar2, 
  313.       error_hint varchar2);
  314.     pragma interface (C, execute_sql);                      -- 1 (see psdicd.c)
  315.  
  316.   procedure alter_compile(type varchar2, schema varchar2, name varchar2) is
  317.     ptype      varchar2(20);
  318.     pschema    varchar2(30);
  319.     pname      varchar2(65);
  320.     owner      varchar2(30);
  321.     part1      varchar2(30);
  322.     part2      varchar2(30);
  323.     dblink     varchar2(30);
  324.     part1_type number;
  325.     objno      number;
  326.   begin
  327.     pschema := schema;
  328.     pname := name;
  329.     if pschema IS NOT NULL then
  330.       pname := pschema || '"."' || pname;
  331.     end if;
  332.     pname := '"' || pname || '"';
  333.  
  334.     begin
  335.       /* name resolve to make sure the object is not a synonym for something
  336.          that we depend on, an hence would cause a deadlock */
  337.       dbms_utility.name_resolve(pname, 1, owner, part1, part2, dblink,
  338.                                 part1_type, objno);
  339.     exception when not_exist3 or no_priv then
  340.       raise_application_error(-20000, 'Unable to compile ' || type || ' ' 
  341.         || pname || ', insufficient privileges or does not exist');
  342.     end;
  343.  
  344.     if (objno is null or dblink is not null) then
  345.       raise_application_error(-20001, 'cannot compile remote ' || type ||
  346.         ' ' || pname);
  347.     end if;
  348.     if owner = 'SYS' 
  349.          and part1 in ('DBMS_STANDARD', 'STANDARD', 'DBMS_DDL') then 
  350.       return;
  351.     end if;
  352.  
  353.     ptype := upper(type);
  354.     commit; -- this commit will fail if in coordinated sesson or
  355.             -- if forms has done 'alter session disable commits ...'
  356.         -- so the 1st two args to execute_sql below are irrelevant
  357.     begin
  358.       if ptype = 'PACKAGE BODY' then
  359.         execute_sql(0, 0, 0, 1, 'alter package ' || pname || ' compile body',
  360.           'ALTER PACKAGE COMPILE');
  361.       elsif ptype = 'PACKAGE' then
  362.         execute_sql(0, 0, 0, 1, 'alter package ' || pname || ' compile',
  363.           'ALTER PACKAGE COMPILE');
  364.       elsif ptype = 'PROCEDURE' or ptype = 'FUNCTION' then
  365.         execute_sql(0, 0, 0, 1, 'alter ' || ptype || ' ' || pname || ' compile',
  366.           'ALTER PROCEDURE COMPILE');
  367.       else
  368.         raise_application_error(-20001, 'bad value for object type: '||ptype);
  369.       end if;
  370.     exception when not_exist1 or not_exist2 or no_priv then
  371.       raise_application_error(-20000, 'Unable to compile ' || type || ' ' 
  372.         || pname || ', insufficient privileges or does not exist');
  373.     end;
  374.     commit;
  375.   end;
  376.  
  377.   procedure analyze_object
  378.     (type varchar2, schema varchar2, name varchar2, method varchar2,
  379.      estimate_rows number default null, 
  380.      estimate_percent number default null) is
  381.     oname  varchar2(65);
  382.     sample varchar2(30) := '';
  383.   begin
  384.     oname := name;
  385.     if schema IS NOT NULL then
  386.       oname := schema || '"."' || name;
  387.     end if;
  388.     oname := '"' || oname || '"';
  389.  
  390.     commit;
  391.    
  392.     -- don't analyze fet$ and uet$, could possibly cause deadlocks
  393.     if schema = 'SYS' and name in ('UET$', 'FET$') then return; end if;
  394.  
  395.     if upper(method) = 'ESTIMATE' then
  396.       if estimate_rows != 0 then
  397.         sample := 'sample '||estimate_rows||' rows';
  398.       elsif estimate_percent != 0 then 
  399.         sample := 'sample '||estimate_percent||' percent';
  400.       end if;
  401.     end if;
  402.  
  403.     begin
  404.       if upper(type) = 'CLUSTER' then
  405.         execute_sql(0, 0, 0, 1,
  406.           'analyze cluster '||oname||' '||method||' statistics '||sample, 
  407.           'ANALYZE CLUSTER');
  408.       elsif upper(type) = 'TABLE' then
  409.         execute_sql(0, 0, 0, 1,
  410.           'analyze table '||oname||' '||method||' statistics '||sample,
  411.           'ANALYZE TABLE');
  412.       elsif upper(type) = 'INDEX' then
  413.         execute_sql(0, 0, 0, 1,
  414.           'analyze index '||oname||' '||method||' statistics '||sample,
  415.           'ANALYZE INDEX');
  416.       else
  417.         raise_application_error(-20001, 'bad value for object type: ' || type);
  418.       end if;
  419.     exception when not_exist0 or not_exist1 or not_exist2 or not_exist4 or
  420.          not_exist5 or no_priv then
  421.       raise_application_error(-20000, 'Unable to analyze ' || type || ' ' 
  422.         || oname || ', insufficient privileges or does not exist');
  423.     end;
  424.     commit;
  425.   end;
  426.  
  427. end;
  428. /
  429.  
  430. create or replace view order_object_by_dependency (dlevel, object_id) as
  431.        select max(level), object_id from public_dependency
  432.        connect by object_id = prior referenced_object_id
  433.        group by object_id
  434. /
  435.  
  436. create or replace view dba_analyze_objects (owner, object_name, object_type) as
  437.        select u.name, o.name, decode(o.type, 2, 'TABLE', 3, 'CLUSTER')
  438.        from sys.user$ u, sys.obj$ o, sys.tab$ t
  439.        where o.owner# = u.user#
  440.        and   o.obj# = t.obj# (+)
  441.        and   t.clu# is null
  442.        and   o.type in (2,3)
  443. /
  444.  
  445. create or replace package body dbms_utility is
  446.   function is_parallel return binary_integer;
  447.     pragma interface (C, is_parallel);                  -- 3 (see psdicd.c)
  448.   function icd_get_time return binary_integer;
  449.     pragma interface (C, icd_get_time);                -- 4 (see psdicd.c)
  450.   procedure icd_name_res(name in varchar2, context in number, 
  451.       schema out varchar2, part1 out varchar2, part2 out varchar2,
  452.       dblink out varchar2, part1_type out binary_integer,
  453.       object_number out binary_integer);
  454.     pragma interface (C, icd_name_res);                -- 5 (see psdicd.c)
  455.   procedure icd_name_tokenize( name    in  varchar2,
  456.                        a       out varchar2,
  457.                        b       out varchar2,
  458.                            c       out varchar2,
  459.                                dblink  out varchar2, 
  460.                                nextpos out binary_integer);
  461.     pragma interface (C, icd_name_tokenize);                -- 6 (see psdicd.c)
  462.   FUNCTION psdpor RETURN VARCHAR2;
  463.     pragma interface (C, psdpor);                           -- 7 (see psdicd.c)
  464.  
  465.   procedure name_resolve(name in varchar2, context in number,
  466.     schema out varchar2, part1 out varchar2, part2 out varchar2,
  467.     dblink out varchar2, part1_type out number, object_number out number) is
  468.   begin
  469.     if context != 1 then
  470.       raise_application_error(-20005, 'ORU-10034: context argument must be 1');
  471.     end if;
  472.     icd_name_res(name, context, schema, part1, part2, dblink, part1_type,
  473.       object_number);
  474.   end;
  475.  
  476.   procedure name_tokenize( name    in  varchar2, 
  477.                    a       out varchar2,
  478.                           b       out varchar2,
  479.                        c       out varchar2,
  480.                    dblink  out varchar2, 
  481.                    nextpos out binary_integer) is
  482.   begin
  483.     icd_name_tokenize( name, a, b, c, dblink, nextpos );
  484.   end;
  485.  
  486.   -- Make a PL/SQL table out of a comma-separated list of names
  487.   --   names :== a [. b [. c ]][ @ d ]
  488.   --   list :== name [ , list ]
  489.   --   Comma_to_table takes a non-empty comma-separated list.  
  490.   --   Anything other than a comma-separated list is rejected.
  491.   --   Commas inside doublequotes do not count.
  492.   --   A PL/SQL table is returned, with values 1..n, and n+1 is null.
  493.   --   The values in tab are cut from the original list; no transformations.
  494.   PROCEDURE comma_to_table( list   IN  VARCHAR2, 
  495.                             tablen OUT BINARY_INTEGER,
  496.                             tab    OUT uncl_array ) IS
  497.     nextpos    BINARY_INTEGER;
  498.     oldpos     BINARY_INTEGER;
  499.     done       BOOLEAN;
  500.     i          BINARY_INTEGER;
  501.     len        BINARY_INTEGER;
  502.     dummy      VARCHAR2(128);
  503.   BEGIN
  504.     -- get ready
  505.     nextpos  := 1;
  506.     done     := FALSE;
  507.     i        := 1;
  508.     len      := NVL(LENGTH(list),0);
  509.  
  510.     WHILE NOT done LOOP
  511.       oldpos := nextpos;
  512.       dbms_utility.name_tokenize( SUBSTR(list,oldpos),
  513.                            dummy, dummy, dummy, dummy, nextpos );
  514.       tab(i) := SUBSTR( list, oldpos, nextpos );
  515.       nextpos := oldpos + nextpos;
  516.       IF nextpos > len THEN
  517.         done := TRUE;
  518.       ELSIF SUBSTR(list,nextpos,1) = ',' then
  519.         nextpos := nextpos + 1;
  520.       ELSE 
  521.         raise_application_error( -20001, 
  522.           'comma-separated list invalid near ' || SUBSTR(list,nextpos-2,5));
  523.       END IF;
  524.       i := i + 1;
  525.     END LOOP;
  526.  
  527.     -- handle the end of the list
  528.     tab(i) := NULL;
  529.     tablen := i-1;
  530.   END;
  531.  
  532.  
  533.   -- Make a comma-separated list out of a PL/SQL table
  534.   --   table_to_comma takes a PL/SQL table, 1..n, terminated with n+1 null.
  535.   --   table_to_comma returns a comma-separated list and 
  536.   --     the number of elements found in the table (n).
  537.   --   Note that ',,,' || ',' || ',,,' = ',,,,,,,'.
  538.   PROCEDURE table_to_comma( tab    IN  uncl_array, 
  539.                             tablen OUT BINARY_INTEGER,
  540.                             list   OUT VARCHAR2) IS
  541.     temp  VARCHAR2(6500) := '';
  542.     i     BINARY_INTEGER :=  1;
  543.   BEGIN
  544.     IF tab(i) IS NOT NULL THEN
  545.       temp := tab(i);
  546.       i    := i + 1;
  547.       WHILE tab(i) IS NOT NULL LOOP
  548.         temp := temp || ',' || tab(i);
  549.         i := i + 1;
  550.       END LOOP;
  551.     END IF;
  552.     tablen := i-1;
  553.     list   := temp;
  554.   EXCEPTION
  555.     WHEN NO_DATA_FOUND THEN
  556.       tablen := i-1;
  557.       list   := temp; 
  558.   END;
  559.  
  560.   function get_time return number is
  561.   begin
  562.     return icd_get_time;
  563.   end;
  564.  
  565.   function is_parallel_server return boolean is
  566.   begin
  567.     if is_parallel = 1 then
  568.       return TRUE;
  569.     else
  570.       return FALSE;
  571.     end if;
  572.   end;
  573.  
  574.   procedure compile_schema (schema varchar2) is
  575.     NOT_EXIST_OR_NO_PRIV exception;
  576.     pragma EXCEPTION_INIT(NOT_EXIST_OR_NO_PRIV, -20000);
  577.  
  578.     cursor c1(schema varchar2) is 
  579.       select a.object_type, a.object_name, a.status
  580.       from sys.order_object_by_dependency p, sys.dba_objects a
  581.       where p.object_id = a.object_id
  582.         and a.owner = c1.schema
  583.       /* need PACKAGE BODY in clause below so that dependency ordering
  584.          is done correctly.  But since compiling a package spec also
  585.          compiles the body (we don't have an 'alter package foo compile
  586.      spec only' command), skip over package bodies in the loop below.
  587.          Then if there are any invalid bodies take care of them in a 
  588.          final pass */
  589.       and (a.object_type = 'FUNCTION' or a.object_type = 'PROCEDURE' or
  590.            a.object_type = 'PACKAGE' or a.object_type = 'PACKAGE BODY')
  591.       order by dlevel desc;
  592.   begin
  593.     for rec in c1(schema) loop
  594.       if rec.object_type <> 'PACKAGE BODY' and (schema <> 'SYS' or
  595.           rec.object_name not in ('DBMS_UTILITY', 'DBMS_SESSION',
  596.           'DBMS_TRANSACTION')) then
  597.         begin
  598.           dbms_ddl.alter_compile(rec.object_type, schema, rec.object_name);
  599.         exception when NOT_EXIST_OR_NO_PRIV then
  600.           raise_application_error(-20000,
  601.             'You have insufficient privileges for an object in this schema.');
  602.         end;
  603.       end if;
  604.     end loop;
  605.  
  606.     -- now look for any bodies which were invalidated after their
  607.     -- compilation due to compilation of other specs.  If we had an
  608.     -- 'alter package foo compile spec only' command then we wouldn't need 
  609.     -- this loop as we could take care of bodies in the loop above without
  610.     -- causing duplicate compiles for all bodies.
  611.     for rec in c1(schema) loop
  612.       if rec.object_type = 'PACKAGE BODY' and rec.status = 'INVALID' and 
  613.           (schema <> 'SYS' or rec.object_name not in ('DBMS_UTILITY',
  614.            'DBMS_SESSION', 'DBMS_TRANSACTION')) then
  615.         begin
  616.           dbms_ddl.alter_compile(rec.object_type, schema, rec.object_name);
  617.         exception when NOT_EXIST_OR_NO_PRIV then
  618.           raise_application_error(-20000,
  619.             'You have insufficient privileges for an object in this schema.');
  620.         end;
  621.       end if;
  622.     end loop;
  623.  
  624.     dbms_session.reset_package;
  625.   end;
  626.  
  627.   procedure analyze_schema(schema varchar2, method varchar2, 
  628.                            estimate_rows number default null, 
  629.                            estimate_percent number default null) is
  630.     NOT_EXIST_OR_NO_PRIV exception;
  631.     pragma EXCEPTION_INIT(NOT_EXIST_OR_NO_PRIV, -20000);
  632.  
  633.     cursor c1(schema varchar2) is 
  634.       select object_name, object_type
  635.       from sys.dba_analyze_objects
  636.       where owner = c1.schema
  637.       order by object_type, object_name;
  638.   begin
  639.     -- analyze all clusters and non-clustered tables in the schema       
  640.     for rec in c1(schema) loop
  641.         begin
  642.           dbms_ddl.analyze_object(rec.object_type, schema, rec.object_name,
  643.                                   method, estimate_rows, estimate_percent);
  644.         exception when NOT_EXIST_OR_NO_PRIV then
  645.           raise_application_error(-20000,
  646.             'You have insufficient privileges for an object in this schema.');
  647.         end;
  648.     end loop;
  649.   end;
  650.  
  651.   FUNCTION port_string RETURN VARCHAR2 IS
  652.   BEGIN
  653.     RETURN(psdpor);
  654.   END port_string;
  655. END dbms_utility;
  656. /
  657.