Files
oracle/vg/genuserdef.sql
2026-03-12 21:23:47 +01:00

551 lines
31 KiB
SQL

SET ECHO off
REM NAME: GENUSERDEF.SQL
REM USAGE:"@path/genuserdef"
REM ------------------------------------------------------------------------
REM REQUIREMENTS:
REM I have set the UTL_FILE_DIR ini the init.ora file to /tmp (on UNIX that is)
REM This is done because all UNIX systems have this directory present and it
REM is writable by all.
REM IF you are going to run this on any other platform, set it to you own
REM favourite directory and make sure that the init.ora files reflect it and
REM that your instance is restarted with this parameter, else you will receive
REM error messages from this script.
REM
REM WARNING -- WARNING -- WARNING -- WARNING
REM This script will currently only work on 8i versions, i.e. 8.1.x or higher
REM ------------------------------------------------------------------------
REM AUTHOR:
REM Svein Erik Brostigen, Oracle Support Services - Orlando, Fl USA
REM Copyright 2000, Oracle Corporation
REM ------------------------------------------------------------------------
REM PURPOSE:
REM Script to create a sql-script that will recreate the schema objects for all
REM users except SYS and SYSTEM in the database.
REM
REM I decided to write this script because we often have customers that have
REM no way of recreating their database objects or even know if anyone
REM have a script that will recreate the objects.
REM
REM
REM These first version does not include partitions or some of the more esoteric
REM features of 8i. I hope to include these in later versions.
REM
REM Any errors that you may find in this script, please mail me any relevant
REM information such as: init.ora file, alert log, your environment, complete
REM error message and any trace files.
REM E-mail to : ebrostig@us.oracle.com
REM
REM History:
REM 0.1 - 09/27/99 ebrostig.us
REM Initial version
REM
REM 0.2 - 10/09/99 ebrostig.us
REM Added clusters, views, triggers
REM
REM 0.3 - 10/20/99 ebrostig.us
REM Added sequnces
REM
REM 0.4 - 11/25/99 ebrostig.us
REM Added creation of users
REM ------------------------------------------------------------------------
REM DISCLAIMER:
REM This script is provided for educational purposes only. It is NOT
REM supported by Oracle World Wide Technical Support.
REM The script has been tested and appears to work as intended.
REM You should always run new scripts on a test instance initially.
REM ------------------------------------------------------------------------
REM Main text of script follows:
declare
first number;
chunk_size number :=254;
chunk_size_returned number;
cur_pos number:=0;
data_chunk varchar2(254);
stmt varchar2(1024);
dir varchar2(1024) := '/tmp';
file_name varchar2(1024) := 'create-schema.sql';
-- Information on all users
v_username sys.all_users.username%TYPE;
-- Information on user accounts from dba_users
v_user_username sys.dba_users.username%TYPE;
v_user_password sys.dba_users.password%TYPE;
v_user_default_tablespace sys.dba_users.default_tablespace%TYPE;
v_user_temporary_tablespace sys.dba_users.temporary_tablespace%TYPE;
v_user_profile sys.dba_users.profile%TYPE;
-- Information on all sequences
v_seq_sequence_name sys.all_sequences.sequence_name%TYPE;
v_seq_min_value sys.all_sequences.min_value%TYPE;
v_seq_max_value sys.all_sequences.max_value%TYPE;
v_seq_increment_by sys.all_sequences.increment_by%TYPE;
v_seq_cycle_flag sys.all_sequences.cycle_flag%TYPE;
v_seq_order_flag sys.all_sequences.order_flag%TYPE;
v_seq_cache_size sys.all_sequences.cache_size%TYPE;
v_seq_last_number sys.all_sequences.last_number%TYPE;
-- Information on all clusters
v_clus_cluster_name sys.all_clusters.cluster_name%TYPE;
v_clus_ts sys.all_clusters.tablespace_name%TYPE;
v_clus_pct_free sys.all_clusters.pct_free%TYPE;
v_clus_pct_used sys.all_clusters.pct_used%TYPE;
v_clus_key_size sys.all_clusters.key_size%TYPE;
v_clus_ini_trans sys.all_clusters.ini_trans%TYPE;
v_clus_max_trans sys.all_clusters.max_trans%TYPE;
v_clus_initial_extent sys.all_clusters.initial_extent%TYPE;
v_clus_next_extent sys.all_clusters.next_extent%TYPE;
v_clus_min_extents sys.all_clusters.min_extents%TYPE;
v_clus_max_extents sys.all_clusters.max_extents%TYPE;
v_clus_pct_increase sys.all_clusters.pct_increase%TYPE;
v_clus_freelists sys.all_clusters.freelists%TYPE;
v_clus_freelist_groups sys.all_clusters.freelist_groups%TYPE;
v_clus_cluster_type sys.all_clusters.cluster_type%TYPE;
v_clus_function sys.all_clusters.function%TYPE;
v_clus_hashkeys sys.all_clusters.hashkeys%TYPE;
v_clus_degree sys.all_clusters.degree%TYPE;
v_clus_cache sys.all_clusters.cache%TYPE;
v_clus_single_table sys.all_clusters.single_table%TYPE;
-- Information on all cluster hash expressions
v_clh_hash_expression sys.all_cluster_hash_expressions.hash_expression%TYPE;
-- Information on all tables
v_owner sys.all_tables.owner%TYPE;
v_table_name sys.all_tables.table_name%TYPE;
v_tablespace_name sys.all_tables.tablespace_name%TYPE;
v_initial_extent sys.all_tables.initial_extent%TYPE;
v_next_extent sys.all_tables.next_extent%TYPE;
v_pct_increase sys.all_tables.pct_increase%TYPE;
v_cluster_name sys.all_tables.cluster_name%TYPE;
v_degree sys.all_tables.degree%TYPE;
v_min_extents sys.all_tables.min_extents%TYPE;
v_max_extents sys.all_tables.max_extents%TYPE;
v_freelists sys.all_tables.freelists%TYPE;
v_freelist_groups sys.all_tables.freelist_groups%TYPE;
v_ini_trans sys.all_tables.ini_trans%TYPE;
v_max_trans sys.all_tables.max_trans%TYPE;
-- Information on columns
v_column_name sys.all_tab_columns.column_name%TYPE;
v_data_type sys.all_tab_columns.data_type%TYPE;
v_data_length sys.all_tab_columns.data_length%TYPE;
v_nullable sys.all_tab_columns.nullable%TYPE;
v_data_precision sys.all_tab_columns.data_precision%TYPE;
-- Information triggers
v_trigger_name sys.all_triggers.trigger_name%TYPE;
v_trigger_type sys.all_triggers.trigger_type%TYPE;
v_triggering_event sys.all_triggers.triggering_event%TYPE;
v_table_owner sys.all_triggers.table_owner%TYPE;
v_trigtab_name sys.all_triggers.table_name%TYPE;
v_when_clause sys.all_triggers.when_clause%TYPE;
v_status sys.all_triggers.status%TYPE;
v_description sys.all_triggers.description%TYPE;
v_trigger_body sys.all_triggers.trigger_body%TYPE;
-- Information on constraints
v_constraint_name sys.all_constraints.constraint_name%TYPE;
v_constraint_type sys.all_constraints.constraint_type%TYPE;
v_cons_status sys.all_constraints.status%TYPE;
-- Information on constraint columns
v_cons_column sys.all_cons_columns.column_name%TYPE;
-- Information on views
v_view_name sys.all_views.view_name%TYPE;
v_text sys.all_views.text%TYPE;
outfile utl_file.file_type;
cursor c_dba_users is
select username, password, default_tablespace, temporary_tablespace, profile from sys.dba_users where username=v_username;
cursor c_user is
select username from all_users where username != 'SYS' and username != 'SYSTEM';
cursor c_sequence is
select sequence_name, min_value, max_value, increment_by, cycle_flag, order_flag, cache_size, last_number
from sys.all_sequences where sequence_owner=v_username;
cursor c_cluster is
select cluster_name, tablespace_name, pct_free, pct_used, key_size, ini_trans, max_trans, initial_extent,
next_extent, min_extents, max_extents, pct_increase, freelists, freelist_groups, cluster_type, function,
hashkeys, degree, cache, single_table from sys.all_clusters where owner=v_username;
cursor c_tables is
select owner, table_name, tablespace_name, initial_extent, next_extent, pct_increase, degree from sys.all_tables
where owner=v_username;
cursor c_columns is
select column_name, data_type, data_length, nullable, data_precision from sys.all_tab_columns where table_name=v_table_name and owner = v_owner;
cursor c_triggers is
select trigger_name, trigger_type, triggering_event, table_owner, table_name, when_clause, status,
description, trigger_body from all_triggers where table_name=v_table_name and owner = v_owner;
cursor c_constraints is
select constraint_name, constraint_type, status from sys.all_constraints where table_name = v_table_name and owner
= v_owner;
cursor c_cons_columns is
select column_name from sys.all_cons_columns where constraint_name = v_constraint_name and owner =
v_owner order by position;
cursor c_views is
select view_name, text from sys.all_views where owner = v_owner order by view_name;
PROCEDURE dump_body(trigger_name IN VARCHAR2, stmt IN varchar2)
IS
data_chunk VARCHAR2(254); -- these can go higher
chunk_size NUMBER:=254; -- up to 32k
chunk_size_returned NUMBER;
mycursor INTEGER;
cur_pos NUMBER:=0;
rows NUMBER;
dummy NUMBER;
status VARCHAR2(50);
tmpfile utl_file.file_type;
BEGIN
tmpfile := utl_file.fopen(dir, file_name, 'a', 32767);
mycursor:=dbms_sql.open_cursor;
dbms_sql.parse(mycursor, stmt, dbms_sql.v7);
dbms_sql.bind_variable(mycursor, ':trigger_name', trigger_name);
dbms_sql.define_column_long(mycursor,1);
dummy:=dbms_sql.execute(mycursor);
rows:=dbms_sql.fetch_rows(mycursor);
loop
-- fetch 'chunks' of the long until we have got the lot
dbms_sql.column_value_long(mycursor,
1,
chunk_size,
cur_pos,
data_chunk,
chunk_size_returned);
utl_file.put(tmpfile, data_chunk); -- use PUT to preserve data
cur_pos:=cur_pos + chunk_size;
exit when chunk_size_returned = 0;
end loop;
dbms_sql.close_cursor(mycursor);
utl_file.fflush(tmpfile);
utl_file.fclose(tmpfile);
EXCEPTION
when utl_file.invalid_path then
raise_application_error(-20100, 'Invalid path in dump_body');
when utl_file.invalid_mode then
raise_application_error(-20101, 'Invalid mode in dump_body');
when utl_file.invalid_operation then
raise_application_error(-20102, 'Invalid operation in dump_body');
when utl_file.invalid_filehandle then
raise_application_error(-20103, 'Invalid filehandle in dump_body');
when utl_file.write_error then
raise_application_error(-20104, 'Write error in dump_body');
when utl_file.read_error then
raise_application_error(-20105, 'Read error in dump_body');
when utl_file.internal_error then
raise_application_error(-20106, 'Internal error in dump_body');
WHEN OTHERS THEN
raise_application_error(-20107, 'Other Error in dump_body');
END dump_body;
-- Begin the main loop...
begin
outfile := utl_file.fopen(dir, file_name, 'w');
utl_file.putf(outfile, '-- Create schema objects script\n--\n-- Version 0.4 11/25/1999\n-- Copyright (c) 1999 Oracle Corp., USA\n-- Written by: ebrostig@us.oracle.com\n\n');
utl_file.putf(outfile, 'Created on %s\n', sysdate);
utl_file.putf(outfile, '\n-- Create all the non system users first...\n');
open c_user;
loop
fetch c_user into v_username;
exit when c_user%NOTFOUND;
open c_dba_users;
loop
fetch c_dba_users into v_user_username, v_user_password, v_user_default_tablespace, v_user_temporary_tablespace, v_user_profile;
exit when c_dba_users%NOTFOUND;
utl_file.putf(outfile, 'CREATE USER %s IDENTIFIED BY VALUES ''%s'' ',v_user_username, v_user_password);
utl_file.putf(outfile, 'DEFAULT TABLESPACE %s TEMPORARY TABLESPACE %s ', v_user_default_tablespace, v_user_temporary_tablespace);
utl_file.putf(outfile, 'PROFILE %s;\n', v_user_profile);
end loop;
close c_dba_users;
end loop;
close c_user;
utl_file.putf(outfile, '\n-- Finished creating all non-system users...\n');
open c_user;
loop
fetch c_user into v_username;
exit when c_user%NOTFOUND;
-- Lets create the sequences, drop them first and creat them afterwards.
-- ?? Should last_number be set as a min_value when the sequences is recreated? Option?
open c_sequence;
loop
fetch c_sequence into v_seq_sequence_name, v_seq_min_value, v_seq_max_value, v_seq_increment_by,
v_seq_cycle_flag, v_seq_order_flag, v_seq_cache_size, v_seq_last_number;
exit when c_sequence%NOTFOUND;
utl_file.putf(outfile, '\n-- Drop sequence first...\n');
utl_file.putf(outfile, 'DROP SEQUENCE %s.%s;\n', v_username, v_seq_sequence_name);
utl_file.putf(outfile, '\n-- Create statement for sequence %s.%s\n\n', v_username,
v_seq_sequence_name);
utl_file.putf(outfile, 'CREATE SEQUENCE %s.%s\n', v_username, v_seq_sequence_name);
utl_file.putf(outfile, 'INCREMENT BY %s\n', v_seq_increment_by);
utl_file.putf(outfile, 'MINVALUE %s\n', v_seq_min_value);
utl_file.putf(outfile, 'MAXVALUE %s\n', v_seq_max_value);
if v_seq_cycle_flag = 'Y' then
utl_file.putf(outfile, 'CYCLE\n');
else
utl_file.putf(outfile, 'NOCYCLE\n');
end if;
if v_seq_order_flag = 'Y' then
utl_file.putf(outfile, 'ORDER\n');
else
utl_file.putf(outfile, 'NOORDER\n');
end if;
if v_seq_cache_size = 0 then
utl_file.putf(outfile, 'NOCACHE;\n');
else
utl_file.putf(outfile, 'CACHE %s;\n', v_seq_cache_size);
end if;
end loop;
close c_sequence;
-- Drop and recreate the clusters. Needs to be done before any tables are created.
open c_cluster;
loop
fetch c_cluster into v_clus_cluster_name, v_clus_ts, v_clus_pct_free, v_clus_pct_used,
v_clus_key_size, v_clus_ini_trans, v_clus_max_trans, v_clus_initial_extent, v_clus_next_extent,
v_clus_min_extents, v_clus_max_extents, v_clus_pct_increase, v_clus_freelists,
v_clus_freelist_groups, v_clus_cluster_type, v_clus_function, v_clus_hashkeys, v_clus_degree,
v_clus_cache, v_clus_single_table;
exit when c_cluster%NOTFOUND;
utl_file.putf(outfile, '\n-- Drop cluster cascade first...\n');
utl_file.putf(outfile, 'DROP CLUSTER %s.%s CASCADE CONSTRAINTS;\n', v_owner, v_clus_cluster_name);
utl_file.putf(outfile, '\n-- Create statement for cluster %s.%s\n\n', v_owner, v_clus_cluster_name);
utl_file.putf(outfile, 'CREATE CLUSTER %s.%s (', v_owner, v_clus_cluster_name);
open c_columns;
first := 1;
loop
fetch c_columns into v_column_name, v_data_type, v_data_length, v_nullable, v_data_precision;
exit when c_columns%NOTFOUND;
if first = 1 then
if v_data_type = 'CHAR' or v_data_type = 'VARCHAR2' or v_data_type = 'NCHAR' or v_data_type = 'NVARCHAR2' or v_data_type = 'RAW' or v_data_type = 'UROWID' then
utl_file.putf(outfile, '\n%s %s(%s)', v_column_name, v_data_type,v_data_length);
elsif v_data_type = 'NUMBER' then
if v_data_precision != '' then
utl_file.putf(outfile, '\n%s %s(%s,%s)', v_column_name, v_data_type,v_data_length,v_data_precision);
else
utl_file.putf(outfile, '\n%s %s(%s)', v_column_name, v_data_type,v_data_length);
end if;
else
utl_file.putf(outfile, '\n%s %s', v_column_name, v_data_type);
end if;
first := 0;
else
if v_data_type = 'CHAR' or v_data_type = 'VARCHAR2' or v_data_type = 'NCHAR' or v_data_type = 'NVARCHAR2' or v_data_type = 'RAW' or v_data_type = 'UROWID' then
utl_file.putf(outfile, ',\n%s %s(%s)', v_column_name, v_data_type,v_data_length);
elsif v_data_type = 'NUMBER' then
if v_data_precision != '' then
utl_file.putf(outfile, ',\n%s %s(%s,%s)', v_column_name, v_data_type,v_data_length,v_data_precision);
else
utl_file.putf(outfile, ',\n%s %s(%s)', v_column_name, v_data_type,v_data_length);
end if;
else
utl_file.putf(outfile, ',\n%s %s', v_column_name, v_data_type);
end if;
end if;
if v_nullable = 'N' then
utl_file.putf(outfile, ' NOT NULL');
end if;
end loop;
close c_columns;
utl_file.putf(outfile, ')\n');
if v_clus_key_size > 0 then
utl_file.putf(outfile, 'SIZE %s ', v_clus_key_size);
end if;
if v_clus_hashkeys > 0 and v_clus_single_table = 'Y' then
utl_file.putf(outfile, 'SINGLE TABLE HASHKEYS %s ', v_clus_hashkeys);
elsif v_clus_hashkeys > 0 and v_clus_single_table = 'N' then
utl_file.putf(outfile, 'HASHKEYS %s ', v_clus_hashkeys);
if v_clus_function != 'NULL' then
utl_file.putf(outfile, 'HASH IS %s\n', v_clus_function);
end if;
end if;
utl_file.putf(outfile, 'STORAGE (INITIAL %s ', v_clus_initial_extent);
utl_file.putf(outfile, ' NEXT %s PCT_INCREASE %s', v_clus_next_extent,v_clus_pct_increase);
utl_file.put(outfile, ') TABLESPACE ');
utl_file.put(outfile, v_clus_ts);
if LTRIM(RTRIM(v_clus_degree)) != '1' and LTRIM(RTRIM(v_clus_degree)) != 'DEFAULT' then
utl_file.putf(outfile, ' PARALLEL %s', LTRIM(RTRIM(v_clus_degree)));
end if;
end loop;
close c_cluster;
open c_tables;
loop
fetch c_tables into v_owner, v_table_name, v_tablespace_name, v_initial_extent,
v_next_extent,v_pct_increase, v_degree;
exit when c_tables%NOTFOUND;
utl_file.putf(outfile, '\n-- Drop table cascade first...\n');
utl_file.putf(outfile, 'DROP TABLE %s.%s CASCADE CONSTRAINTS;\n', v_owner, v_table_name);
utl_file.putf(outfile,'\n-- Create statement for table %s.%s\n\n', v_owner, v_table_name);
utl_file.put(outfile, 'CREATE TABLE ');
utl_file.put(outfile, v_owner);
utl_file.put(outfile, '.');
utl_file.put(outfile, v_table_name);
utl_file.put(outfile, ' ( ');
open c_columns;
first := 1;
loop
fetch c_columns into v_column_name, v_data_type, v_data_length, v_nullable, v_data_precision;
exit when c_columns%NOTFOUND;
if first = 1 then
if v_data_type = 'CHAR' or v_data_type = 'VARCHAR2' or v_data_type = 'NCHAR' or v_data_type = 'NVARCHAR2' or v_data_type = 'RAW' or v_data_type = 'UROWID' then
utl_file.putf(outfile, '\n%s %s(%s)', v_column_name, v_data_type,v_data_length);
elsif v_data_type = 'NUMBER' then
if v_data_precision != '' then
utl_file.putf(outfile, '\n%s %s(%s,%s)', v_column_name, v_data_type,v_data_length,v_data_precision);
else
utl_file.putf(outfile, '\n%s %s(%s)', v_column_name, v_data_type,v_data_length);
end if;
else
utl_file.putf(outfile, '\n%s %s', v_column_name, v_data_type);
end if;
first := 0;
else
if v_data_type = 'CHAR' or v_data_type = 'VARCHAR2' or v_data_type = 'NCHAR' or v_data_type = 'NVARCHAR2' or v_data_type = 'RAW' or v_data_type = 'UROWID' then
utl_file.putf(outfile, ',\n%s %s(%s)', v_column_name, v_data_type,v_data_length);
elsif v_data_type = 'NUMBER' then
if v_data_precision != '' then
utl_file.putf(outfile, ',\n%s %s(%s,%s)', v_column_name, v_data_type,v_data_length,v_data_precision);
else
utl_file.putf(outfile, ',\n%s %s(%s)', v_column_name, v_data_type,v_data_length);
end if;
else
utl_file.putf(outfile, ',\n%s %s', v_column_name, v_data_type);
end if;
end if;
if v_nullable = 'N' then
utl_file.putf(outfile, ' NOT NULL');
end if;
end loop;
close c_columns;
utl_file.putf(outfile, ')\n STORAGE (INITIAL %s ', v_initial_extent);
utl_file.putf(outfile, ' NEXT %s PCT_INCREASE %s', v_next_extent,v_pct_increase);
utl_file.put(outfile, ') TABLESPACE ');
utl_file.put(outfile, v_tablespace_name);
if LTRIM(RTRIM(v_degree)) != '1' and LTRIM(RTRIM(v_degree)) != 'DEFAULT' then
utl_file.putf(outfile, ' PARALLEL %s', LTRIM(RTRIM(v_degree)));
end if;
utl_file.put(outfile, ';');
utl_file.new_line(outfile);
utl_file.fflush(outfile);
-- Now create triggers for the table...
utl_file.putf(outfile,'\n-- Creating triggers for table %s.%s\n\n', v_owner, v_table_name);
stmt:='SELECT TRIGGER_BODY FROM SYS.ALL_TRIGGERS WHERE TRIGGER_NAME = :trigger_name';
open c_triggers;
loop
fetch c_triggers into v_trigger_name, v_trigger_type, v_triggering_event, v_table_owner,
v_trigtab_name, v_when_clause, v_status, v_description, v_trigger_body;
exit when c_triggers%NOTFOUND;
utl_file.putf(outfile,'CREATE OR REPLACE TRIGGER %s.%s %s ', v_table_owner, v_trigger_name,
v_trigger_type);
utl_file.putf(outfile, '%s ON %s.%s\n', v_triggering_event, v_table_owner, v_trigtab_name);
utl_file.putf(outfile, 'WHEN %s\n', v_when_clause);
utl_file.fclose(outfile);
dump_body(v_trigger_name, stmt);
outfile := utl_file.fopen(dir, file_name,'a');
utl_file.putf(outfile, '\nEND;\n');
utl_file.fflush(outfile);
end loop;
close c_triggers;
-- Now create primary keys and indexes...
utl_file.putf(outfile,'\n-- Creating constraints for table %s.%s\n\n', v_owner, v_table_name);
open c_constraints;
loop
fetch c_constraints into v_constraint_name, v_constraint_type, v_cons_status;
exit when c_constraints%NOTFOUND;
-- Primary Key Constraint
if v_constraint_type = 'P' then
utl_file.putf(outfile, 'ALTER TABLE %s ADD PRIMARY KEY (', v_table_name);
first := 1;
open c_cons_columns;
loop
fetch c_cons_columns into v_cons_column;
exit when c_cons_columns%NOTFOUND;
if first = 1 then
utl_file.putf(outfile, '%s', v_cons_column);
first := 0;
else
utl_file.putf(outfile, ',%s', v_cons_column);
end if;
end loop;
close c_cons_columns;
utl_file.putf(outfile, ') %s;\n\n', v_cons_status);
elsif v_constraint_type = 'U' then -- Unique Key Constraint
utl_file.putf(outfile, 'ALTER TABLE %s ADD CONSTRAINT %s\nUNIQUE (', v_table_name, v_constraint_name);
first := 1;
open c_cons_columns;
loop
fetch c_cons_columns into v_cons_column;
exit when c_cons_columns%NOTFOUND;
if first = 1 then
utl_file.putf(outfile, '%s', v_cons_column);
first := 0;
else
utl_file.putf(outfile, ',%s', v_cons_column);
end if;
end loop;
close c_cons_columns;
utl_file.putf(outfile, ');\n\n');
end if;
end loop;
close c_constraints;
end loop;
close c_tables;
-- Create views
utl_file.putf(outfile,'\n-- Creating views for user %s\n\n', v_owner);
stmt := 'SELECT TEXT FROM SYS.ALL_VIEWS WHERE VIEW_NAME =:trigger_name';
open c_views;
loop
fetch c_views into v_view_name, v_text;
exit when c_views%NOTFOUND;
utl_file.putf(outfile, 'CREATE OR REPLACE VIEW %s\nAS ', v_view_name);
utl_file.fflush(outfile);
utl_file.fclose(outfile);
dump_body(v_view_name, stmt);
outfile := utl_file.fopen(dir, file_name,'a');
utl_file.putf(outfile, ';\n\n');
end loop;
close c_views;
end loop;
utl_file.fclose(outfile);
end;
/