2026-03-12 20:23:15

This commit is contained in:
root
2026-03-12 21:23:47 +01:00
parent eab4b36eca
commit 93039b8489
3332 changed files with 699614 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/analyze_all.sql
-- Author : Tim Hall
-- Description : Outdated script to analyze all tables for the specified schema.
-- Comment : Use DBMS_UTILITY.ANALYZE_SCHEMA or DBMS_STATS.GATHER_SCHEMA_STATS if your server allows it.
-- Call Syntax : @ananlyze_all (schema-name)
-- Last Modified: 26/02/2002
-- -----------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ANALYZE TABLE "' || table_name || '" COMPUTE STATISTICS;'
FROM all_tables
WHERE owner = Upper('&1')
ORDER BY 1;
SPOOL OFF
-- Comment out following line to prevent immediate run
@temp.sql
SET PAGESIZE 14
SET FEEDBACK ON
SET VERIFY ON

View File

@@ -0,0 +1,30 @@
CREATE OR REPLACE FUNCTION base64decode(p_clob CLOB)
RETURN BLOB
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/base64decode.sql
-- Author : Tim Hall
-- Description : Decodes a Base64 CLOB into a BLOB
-- Last Modified: 09/11/2011
-- -----------------------------------------------------------------------------------
IS
l_blob BLOB;
l_raw RAW(32767);
l_amt NUMBER := 7700;
l_offset NUMBER := 1;
l_temp VARCHAR2(32767);
BEGIN
BEGIN
DBMS_LOB.createtemporary (l_blob, FALSE, DBMS_LOB.CALL);
LOOP
DBMS_LOB.read(p_clob, l_amt, l_offset, l_temp);
l_offset := l_offset + l_amt;
l_raw := UTL_ENCODE.base64_decode(UTL_RAW.cast_to_raw(l_temp));
DBMS_LOB.append (l_blob, TO_BLOB(l_raw));
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
RETURN l_blob;
END;
/

View File

@@ -0,0 +1,18 @@
CREATE OR REPLACE FUNCTION base64encode(p_blob IN BLOB)
RETURN CLOB
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/base64encode.sql
-- Author : Tim Hall
-- Description : Encodes a BLOB into a Base64 CLOB.
-- Last Modified: 09/11/2011
-- -----------------------------------------------------------------------------------
IS
l_clob CLOB;
l_step PLS_INTEGER := 12000; -- make sure you set a multiple of 3 not higher than 24573
BEGIN
FOR i IN 0 .. TRUNC((DBMS_LOB.getlength(p_blob) - 1 )/l_step) LOOP
l_clob := l_clob || UTL_RAW.cast_to_varchar2(UTL_ENCODE.base64_encode(DBMS_LOB.substr(p_blob, l_step, i * l_step + 1)));
END LOOP;
RETURN l_clob;
END;
/

View File

@@ -0,0 +1,33 @@
CREATE OR REPLACE FUNCTION blob_to_clob (p_data IN BLOB)
RETURN CLOB
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/blob_to_clob.sql
-- Author : Tim Hall
-- Description : Converts a BLOB to a CLOB.
-- Last Modified: 26/12/2016
-- -----------------------------------------------------------------------------------
AS
l_clob CLOB;
l_dest_offset PLS_INTEGER := 1;
l_src_offset PLS_INTEGER := 1;
l_lang_context PLS_INTEGER := DBMS_LOB.default_lang_ctx;
l_warning PLS_INTEGER;
BEGIN
DBMS_LOB.createTemporary(
lob_loc => l_clob,
cache => TRUE);
DBMS_LOB.converttoclob(
dest_lob => l_clob,
src_blob => p_data,
amount => DBMS_LOB.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset,
blob_csid => DBMS_LOB.default_csid,
lang_context => l_lang_context,
warning => l_warning);
RETURN l_clob;
END;
/

View File

@@ -0,0 +1,41 @@
CREATE OR REPLACE PROCEDURE blob_to_file (p_blob IN BLOB,
p_dir IN VARCHAR2,
p_filename IN VARCHAR2)
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/blob_to_file.sql
-- Author : Tim Hall
-- Description : Writes the contents of a BLOB to a file.
-- Last Modified: 26/02/2019 - Taken from 2005 article.
-- 22/05/2020 - BLOB parameter switched from IN OUT NOCOPY to IN.
-- -----------------------------------------------------------------------------------
AS
l_file UTL_FILE.FILE_TYPE;
l_buffer RAW(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_blob_len INTEGER;
BEGIN
l_blob_len := DBMS_LOB.getlength(p_blob);
-- Open the destination file.
l_file := UTL_FILE.fopen(p_dir, p_filename,'wb', 32767);
-- Read chunks of the BLOB and write them to the file until complete.
WHILE l_pos <= l_blob_len LOOP
DBMS_LOB.read(p_blob, l_amount, l_pos, l_buffer);
UTL_FILE.put_raw(l_file, l_buffer, TRUE);
l_pos := l_pos + l_amount;
END LOOP;
-- Close the file.
UTL_FILE.fclose(l_file);
EXCEPTION
WHEN OTHERS THEN
-- Close the file if something goes wrong.
IF UTL_FILE.is_open(l_file) THEN
UTL_FILE.fclose(l_file);
END IF;
RAISE;
END blob_to_file;
/

View File

@@ -0,0 +1,33 @@
CREATE OR REPLACE FUNCTION clob_to_blob (p_data IN CLOB)
RETURN BLOB
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/clob_to_blob.sql
-- Author : Tim Hall
-- Description : Converts a CLOB to a BLOB.
-- Last Modified: 26/12/2016
-- -----------------------------------------------------------------------------------
AS
l_blob BLOB;
l_dest_offset PLS_INTEGER := 1;
l_src_offset PLS_INTEGER := 1;
l_lang_context PLS_INTEGER := DBMS_LOB.default_lang_ctx;
l_warning PLS_INTEGER := DBMS_LOB.warn_inconvertible_char;
BEGIN
DBMS_LOB.createtemporary(
lob_loc => l_blob,
cache => TRUE);
DBMS_LOB.converttoblob(
dest_lob => l_blob,
src_clob => p_data,
amount => DBMS_LOB.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset,
blob_csid => DBMS_LOB.default_csid,
lang_context => l_lang_context,
warning => l_warning);
RETURN l_blob;
END;
/

View File

@@ -0,0 +1,36 @@
CREATE OR REPLACE PROCEDURE clob_to_file (p_clob IN CLOB,
p_dir IN VARCHAR2,
p_filename IN VARCHAR2)
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/clob_to_file.sql
-- Author : Tim Hall
-- Description : Writes the contents of a CLOB to a file.
-- Last Modified: 26/02/2019 - Taken from 2005 article.
-- 22/05/2020 - BLOB parameter switched from IN OUT NOCOPY to IN.
-- -----------------------------------------------------------------------------------
AS
l_file UTL_FILE.FILE_TYPE;
l_buffer VARCHAR2(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
BEGIN
l_file := UTL_FILE.fopen(p_dir, p_filename, 'w', 32767);
LOOP
DBMS_LOB.read (p_clob, l_amount, l_pos, l_buffer);
UTL_FILE.put(l_file, l_buffer);
l_pos := l_pos + l_amount;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Expected end.
IF UTL_FILE.is_open(l_file) THEN
UTL_FILE.fclose(l_file);
END IF;
WHEN OTHERS THEN
IF UTL_FILE.is_open(l_file) THEN
UTL_FILE.fclose(l_file);
END IF;
RAISE;
END clob_to_file;
/

View File

@@ -0,0 +1,19 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/column_comments.sql
-- Author : Tim Hall
-- Description : Displays comments associate with specific tables.
-- Requirements : Access to the DBA views.
-- Call Syntax : @column_comments (schema) (table-name)
-- Last Modified: 15/07/2000
-- -----------------------------------------------------------------------------------
SET VERIFY OFF
SET PAGESIZE 100
COLUMN column_name FORMAT A20
COLUMN comments FORMAT A50
SELECT column_name,
comments
FROM dba_col_comments
WHERE owner = UPPER('&1')
AND table_name = UPPER('&2')
ORDER BY column_name;

View File

@@ -0,0 +1,30 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/comments.sql
-- Author : Tim Hall
-- Description : Displays all comments for the specified table and its columns.
-- Call Syntax : @comments (table-name) (schema-name)
-- Last Modified: 15/07/2000
-- -----------------------------------------------------------------------------------
PROMPT
SET VERIFY OFF
SET FEEDBACK OFF
SET LINESIZE 255
SET PAGESIZE 1000
SELECT a.table_name "Table",
a.table_type "Type",
Substr(a.comments,1,200) "Comments"
FROM all_tab_comments a
WHERE a.table_name = Upper('&1')
AND a.owner = Upper('&2');
SELECT a.column_name "Column",
Substr(a.comments,1,200) "Comments"
FROM all_col_comments a
WHERE a.table_name = Upper('&1')
AND a.owner = Upper('&2');
SET VERIFY ON
SET FEEDBACK ON
SET PAGESIZE 14
PROMPT

View File

@@ -0,0 +1,13 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/compile_all.sql
-- Author : Tim Hall
-- Description : Compiles all invalid objects for specified schema, or all schema.
-- Requirements : Requires all other "Compile_All" scripts.
-- Call Syntax : @compile_all (schema-name or all)
-- Last Modified: 15/07/2000
-- -----------------------------------------------------------------------------------
@Compile_All_Specs &&1
@Compile_All_Bodies &&1
@Compile_All_Procs &&1
@Compile_All_Funcs &&1
@Compile_All_Views &&1

View File

@@ -0,0 +1,27 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/compile_all_bodies.sql
-- Author : Tim Hall
-- Description : Compiles all invalid package bodies for specified schema, or all schema.
-- Call Syntax : @compile_all_bodies (schema-name or all)
-- Last Modified: 28/01/2001
-- -----------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER PACKAGE ' || a.owner || '.' || a.object_name || ' COMPILE BODY;'
FROM all_objects a
WHERE a.object_type = 'PACKAGE BODY'
AND a.status = 'INVALID'
AND a.owner = Decode(Upper('&&1'), 'ALL',a.owner, Upper('&&1'));
SPOOL OFF
-- Comment out following line to prevent immediate run
@temp.sql
SET PAGESIZE 14
SET FEEDBACK ON
SET VERIFY ON

View File

@@ -0,0 +1,27 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/compile_all_funcs.sql
-- Author : Tim Hall
-- Description : Compiles all invalid functions for specified schema, or all schema.
-- Call Syntax : @compile_all_funcs (schema-name or all)
-- Last Modified: 28/01/2001
-- -----------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER FUNCTION ' || a.owner || '.' || a.object_name || ' COMPILE;'
FROM all_objects a
WHERE a.object_type = 'FUNCTION'
AND a.status = 'INVALID'
AND a.owner = Decode(Upper('&&1'), 'ALL',a.owner, Upper('&&1'));
SPOOL OFF
-- Comment out following line to prevent immediate run
@temp.sql
SET PAGESIZE 14
SET FEEDBACK ON
SET VERIFY ON

View File

@@ -0,0 +1,27 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/compile_all_procs.sql
-- Author : Tim Hall
-- Description : Compiles all invalid procedures for specified schema, or all schema.
-- Call Syntax : @compile_all_procs (schema-name or all)
-- Last Modified: 28/01/2001
-- -----------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER PROCEDURE ' || a.owner || '.' || a.object_name || ' COMPILE;'
FROM all_objects a
WHERE a.object_type = 'PROCEDURE'
AND a.status = 'INVALID'
AND a.owner = Decode(Upper('&&1'), 'ALL',a.owner, Upper('&&1'));
SPOOL OFF
-- Comment out following line to prevent immediate run
@temp.sql
SET PAGESIZE 14
SET FEEDBACK ON
SET VERIFY ON

View File

@@ -0,0 +1,27 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/compile_all_specs.sql
-- Author : Tim Hall
-- Description : Compiles all invalid package specifications for specified schema, or all schema.
-- Call Syntax : @compile_all_specs (schema-name or all)
-- Last Modified: 28/01/2001
-- -----------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER PACKAGE ' || a.owner || '.' || a.object_name || ' COMPILE;'
FROM all_objects a
WHERE a.object_type = 'PACKAGE'
AND a.status = 'INVALID'
AND a.owner = Decode(Upper('&&1'), 'ALL',a.owner, Upper('&&1'));
SPOOL OFF
-- Comment out following line to prevent immediate run
@temp.sql
SET PAGESIZE 14
SET FEEDBACK ON
SET VERIFY ON

View File

@@ -0,0 +1,27 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/compile_all_trigs.sql
-- Author : Tim Hall
-- Description : Compiles all invalid triggers for specified schema, or all schema.
-- Call Syntax : @compile_all_trigs (schema-name or all)
-- Last Modified: 28/01/2001
-- -----------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER TRIGGER ' || a.owner || '.' || a.object_name || ' COMPILE;'
FROM all_objects a
WHERE a.object_type = 'TRIGGER'
AND a.status = 'INVALID'
AND a.owner = Decode(Upper('&&1'), 'ALL',a.owner, Upper('&&1'));
SPOOL OFF
-- Comment out following line to prevent immediate run
@temp.sql
SET PAGESIZE 14
SET FEEDBACK ON
SET VERIFY ON

View File

@@ -0,0 +1,27 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/compile_all_views.sql
-- Author : Tim Hall
-- Description : Compiles all invalid views for specified schema, or all schema.
-- Call Syntax : @compile_all_views (schema-name or all)
-- Last Modified: 28/01/2001
-- -----------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER VIEW ' || a.owner || '.' || a.object_name || ' COMPILE;'
FROM all_objects a
WHERE a.object_type = 'VIEW'
AND a.status = 'INVALID'
AND a.owner = Decode(Upper('&&1'), 'ALL',a.owner, Upper('&&1'));
SPOOL OFF
-- Comment out following line to prevent immediate run
@temp.sql
SET PAGESIZE 14
SET FEEDBACK ON
SET VERIFY ON

View File

@@ -0,0 +1,106 @@
CREATE OR REPLACE PACKAGE conversion_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/conversion_api.sql
-- Author : Tim Hall
-- Description : Provides some base conversion functions.
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 10-SEP-2003 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
FUNCTION to_base(p_dec IN NUMBER,
p_base IN NUMBER) RETURN VARCHAR2;
FUNCTION to_dec (p_str IN VARCHAR2,
p_from_base IN NUMBER DEFAULT 16) RETURN NUMBER;
FUNCTION to_hex(p_dec IN NUMBER) RETURN VARCHAR2;
FUNCTION to_bin(p_dec IN NUMBER) RETURN VARCHAR2;
FUNCTION to_oct(p_dec IN NUMBER) RETURN VARCHAR2;
END conversion_api;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY conversion_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/conversion_api.sql
-- Author : Tim Hall
-- Description : Provides some base conversion functions.
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 10-SEP-2003 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
FUNCTION to_base(p_dec IN NUMBER,
p_base IN NUMBER) RETURN VARCHAR2 IS
-- ----------------------------------------------------------------------------
l_str VARCHAR2(255) DEFAULT NULL;
l_num NUMBER DEFAULT p_dec;
l_hex VARCHAR2(16) DEFAULT '0123456789ABCDEF';
BEGIN
IF (TRUNC(p_dec) <> p_dec OR p_dec < 0) THEN
RAISE PROGRAM_ERROR;
END IF;
LOOP
l_str := SUBSTR(l_hex, MOD(l_num,p_base)+1, 1) || l_str;
l_num := TRUNC(l_num/p_base);
EXIT WHEN (l_num = 0);
END LOOP;
RETURN l_str;
END to_base;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
FUNCTION to_dec (p_str IN VARCHAR2,
p_from_base IN NUMBER DEFAULT 16) RETURN NUMBER IS
-- ----------------------------------------------------------------------------
l_num NUMBER DEFAULT 0;
l_hex VARCHAR2(16) DEFAULT '0123456789ABCDEF';
BEGIN
FOR i IN 1 .. LENGTH(p_str) LOOP
l_num := l_num * p_from_base + INSTR(l_hex,UPPER(SUBSTR(p_str,i,1)))-1;
END LOOP;
RETURN l_num;
END to_dec;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
FUNCTION to_hex(p_dec IN NUMBER) RETURN VARCHAR2 IS
-- ----------------------------------------------------------------------------
BEGIN
RETURN to_base(p_dec, 16);
END to_hex;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
FUNCTION to_bin(p_dec IN NUMBER) RETURN VARCHAR2 IS
-- ----------------------------------------------------------------------------
BEGIN
RETURN to_base(p_dec, 2);
END to_bin;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
FUNCTION to_oct(p_dec IN NUMBER) RETURN VARCHAR2 IS
-- ----------------------------------------------------------------------------
BEGIN
RETURN to_base(p_dec, 8);
END to_oct;
-- ----------------------------------------------------------------------------
END conversion_api;
/
SHOW ERRORS

View File

@@ -0,0 +1,304 @@
CREATE OR REPLACE PACKAGE csv AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/cvs.sql
-- Author : Tim Hall
-- Description : Basic CSV API. For usage notes see:
-- https://oracle-base.com/articles/9i/GeneratingCSVFiles.php
--
-- CREATE OR REPLACE DIRECTORY dba_dir AS '/u01/app/oracle/dba/';
-- ALTER SESSION SET NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS';
--
-- EXEC csv.generate('DBA_DIR', 'generate.csv', p_query => 'SELECT * FROM emp');
--
-- Requirements : UTL_FILE, DBMS_SQL
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 14-MAY-2005 Tim Hall Initial Creation
-- 19-MAY-2016 Tim Hall Add REF CURSOR support.
-- 15-JAN-2019 Tim Hall Add DBMS_OUTPUT support.
-- 31-JAN-2019 Tim Hall Add set_quotes procedure.
-- 22-NOV-2020 Tim Hall Amend set_quotes to allow control of string escaping.
-- --------------------------------------------------------------------------
PROCEDURE generate (p_dir IN VARCHAR2,
p_file IN VARCHAR2,
p_query IN VARCHAR2);
PROCEDURE generate_rc (p_dir IN VARCHAR2,
p_file IN VARCHAR2,
p_refcursor IN OUT SYS_REFCURSOR);
PROCEDURE output (p_query IN VARCHAR2);
PROCEDURE output_rc (p_refcursor IN OUT SYS_REFCURSOR);
PROCEDURE set_separator (p_sep IN VARCHAR2);
PROCEDURE set_quotes (p_add_quotes IN BOOLEAN := TRUE,
p_quote_char IN VARCHAR2 := '"',
p_escape IN BOOLEAN := TRUE);
END csv;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY csv AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/cvs.sql
-- Author : Tim Hall
-- Description : Basic CSV API. For usage notes see:
-- https://oracle-base.com/articles/9i/GeneratingCSVFiles.php
--
-- CREATE OR REPLACE DIRECTORY dba_dir AS '/u01/app/oracle/dba/';
-- ALTER SESSION SET NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS';
--
-- -- Query
-- EXEC csv.generate('DBA_DIR', 'generate.csv', p_query => 'SELECT * FROM emp');
--
-- -- Ref Cursor
-- DECLARE
-- l_refcursor SYS_REFCURSOR;
-- BEGIN
-- OPEN l_refcursor FOR
-- SELECT * FROM emp;
--
-- csv.generate_rc('DBA_DIR','generate.csv', l_refcursor);
-- END;
-- /
--
--
-- Requirements : UTL_FILE, DBMS_SQL
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 14-MAY-2005 Tim Hall Initial Creation
-- 19-MAY-2016 Tim Hall Add REF CURSOR support.
-- 15-JAN-2019 Tim Hall Add DBMS_OUTPUT support.
-- 31-JAN-2019 Tim Hall Add quotes to strings. Code suggested by Moose T.
-- 22-NOV-2020 Tim Hall Amend set_quotes to allow control of string escaping.
-- Amend generate_all to include optional string escapes.
-- Suggested by Anssi Kanninen.
-- 02-MAR-2021 Tim Hall Amend generate_all to also escape the escape character
-- when present in the string.
-- Suggested by Anssi Kanninen.
-- --------------------------------------------------------------------------
g_out_type VARCHAR2(1) := 'F';
g_sep VARCHAR2(5) := ',';
g_add_quotes BOOLEAN := TRUE;
g_quote_char VARCHAR2(1) := '"';
g_escape BOOLEAN := TRUE;
-- Prototype for hidden procedures.
PROCEDURE generate_all (p_dir IN VARCHAR2,
p_file IN VARCHAR2,
p_query IN VARCHAR2,
p_refcursor IN OUT SYS_REFCURSOR);
PROCEDURE put (p_file IN UTL_FILE.file_type,
p_text IN VARCHAR2);
PROCEDURE new_line (p_file IN UTL_FILE.file_type);
-- Stub to generate a CSV from a query.
PROCEDURE generate (p_dir IN VARCHAR2,
p_file IN VARCHAR2,
p_query IN VARCHAR2) AS
l_cursor SYS_REFCURSOR;
BEGIN
g_out_type := 'F';
generate_all (p_dir => p_dir,
p_file => p_file,
p_query => p_query,
p_refcursor => l_cursor);
END generate;
-- Stub to generate a CVS from a REF CURSOR.
PROCEDURE generate_rc (p_dir IN VARCHAR2,
p_file IN VARCHAR2,
p_refcursor IN OUT SYS_REFCURSOR) AS
BEGIN
g_out_type := 'F';
generate_all (p_dir => p_dir,
p_file => p_file,
p_query => NULL,
p_refcursor => p_refcursor);
END generate_rc;
-- Stub to output a CSV from a query.
PROCEDURE output (p_query IN VARCHAR2) AS
l_cursor SYS_REFCURSOR;
BEGIN
g_out_type := 'D';
generate_all (p_dir => NULL,
p_file => NULL,
p_query => p_query,
p_refcursor => l_cursor);
END output;
-- Stub to output a CVS from a REF CURSOR.
PROCEDURE output_rc (p_refcursor IN OUT SYS_REFCURSOR) AS
BEGIN
g_out_type := 'D';
generate_all (p_dir => NULL,
p_file => NULL,
p_query => NULL,
p_refcursor => p_refcursor);
END output_rc;
-- Do the actual work.
PROCEDURE generate_all (p_dir IN VARCHAR2,
p_file IN VARCHAR2,
p_query IN VARCHAR2,
p_refcursor IN OUT SYS_REFCURSOR) AS
l_cursor PLS_INTEGER;
l_rows PLS_INTEGER;
l_col_cnt PLS_INTEGER;
l_desc_tab DBMS_SQL.desc_tab2;
l_buffer VARCHAR2(32767);
l_is_str BOOLEAN;
l_file UTL_FILE.file_type;
BEGIN
IF p_query IS NOT NULL THEN
l_cursor := DBMS_SQL.open_cursor;
DBMS_SQL.parse(l_cursor, p_query, DBMS_SQL.native);
ELSIF p_refcursor%ISOPEN THEN
l_cursor := DBMS_SQL.to_cursor_number(p_refcursor);
ELSE
RAISE_APPLICATION_ERROR(-20000, 'You must specify a query or a REF CURSOR.');
END IF;
DBMS_SQL.describe_columns2 (l_cursor, l_col_cnt, l_desc_tab);
FOR i IN 1 .. l_col_cnt LOOP
DBMS_SQL.define_column(l_cursor, i, l_buffer, 32767 );
END LOOP;
IF p_query IS NOT NULL THEN
l_rows := DBMS_SQL.execute(l_cursor);
END IF;
IF g_out_type = 'F' THEN
l_file := UTL_FILE.fopen(p_dir, p_file, 'w', 32767);
END IF;
-- Output the column names.
FOR i IN 1 .. l_col_cnt LOOP
IF i > 1 THEN
put(l_file, g_sep);
END IF;
put(l_file, l_desc_tab(i).col_name);
END LOOP;
new_line(l_file);
-- Output the data.
LOOP
EXIT WHEN DBMS_SQL.fetch_rows(l_cursor) = 0;
FOR i IN 1 .. l_col_cnt LOOP
IF i > 1 THEN
put(l_file, g_sep);
END IF;
-- Check if this is a string column.
l_is_str := FALSE;
IF l_desc_tab(i).col_type IN (DBMS_TYPES.typecode_varchar,
DBMS_TYPES.typecode_varchar2,
DBMS_TYPES.typecode_char,
DBMS_TYPES.typecode_clob,
DBMS_TYPES.typecode_nvarchar2,
DBMS_TYPES.typecode_nchar,
DBMS_TYPES.typecode_nclob) THEN
l_is_str := TRUE;
END IF;
DBMS_SQL.COLUMN_VALUE(l_cursor, i, l_buffer);
-- Optionally add quotes for strings.
IF g_add_quotes AND l_is_str THEN
put(l_file, g_quote_char);
-- Optionally escape the quote character and the escape character in the string.
IF g_escape THEN
l_buffer := replace(l_buffer, '\', '\\');
l_buffer := replace(l_buffer, g_quote_char, '\'||g_quote_char);
END IF;
put(l_file, l_buffer);
put(l_file, g_quote_char);
ELSE
put(l_file, l_buffer);
END IF;
END LOOP;
new_line(l_file);
END LOOP;
IF UTL_FILE.is_open(l_file) THEN
UTL_FILE.fclose(l_file);
END IF;
DBMS_SQL.close_cursor(l_cursor);
EXCEPTION
WHEN OTHERS THEN
IF UTL_FILE.is_open(l_file) THEN
UTL_FILE.fclose(l_file);
END IF;
IF DBMS_SQL.is_open(l_cursor) THEN
DBMS_SQL.close_cursor(l_cursor);
END IF;
DBMS_OUTPUT.put_line('ERROR: ' || DBMS_UTILITY.format_error_backtrace);
RAISE;
END generate_all;
-- Alter separator from default.
PROCEDURE set_separator (p_sep IN VARCHAR2) AS
BEGIN
g_sep := p_sep;
END set_separator;
-- Alter separator from default.
PROCEDURE set_quotes (p_add_quotes IN BOOLEAN := TRUE,
p_quote_char IN VARCHAR2 := '"',
p_escape IN BOOLEAN := TRUE) AS
BEGIN
g_add_quotes := NVL(p_add_quotes, TRUE);
g_quote_char := NVL(SUBSTR(p_quote_char,1,1), '"');
g_escape := NVL(p_escape, TRUE);
END set_quotes;
-- Handle put to file or screen.
PROCEDURE put (p_file IN UTL_FILE.file_type,
p_text IN VARCHAR2) AS
BEGIN
IF g_out_type = 'F' THEN
UTL_FILE.put(p_file, p_text);
ELSE
DBMS_OUTPUT.put(p_text);
END IF;
END put;
-- Handle newline to file or screen.
PROCEDURE new_line (p_file IN UTL_FILE.file_type) AS
BEGIN
IF g_out_type = 'F' THEN
UTL_FILE.new_line(p_file);
ELSE
DBMS_OUTPUT.new_line;
END IF;
END new_line;
END csv;
/
SHOW ERRORS

View File

@@ -0,0 +1,47 @@
CREATE OR REPLACE PACKAGE date_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/date_api.sql
-- Author : Tim Hall
-- Description : A package to hold date utilities.
-- Requirements :
-- Amendments :
-- When Who What
-- =========== ======== =================================================
-- 04-FEB-2015 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
FUNCTION oracle_to_unix (p_date IN DATE) RETURN NUMBER;
FUNCTION unix_to_oracle (p_unix IN NUMBER) RETURN DATE;
END date_api;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY date_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/date_api.sql
-- Author : Tim Hall
-- Description : A package to hold date utilities.
-- Requirements :
-- Amendments :
-- When Who What
-- =========== ======== =================================================
-- 04-FEB-2015 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
FUNCTION oracle_to_unix (p_date IN DATE) RETURN NUMBER AS
l_number NUMBER;
BEGIN
l_number := (p_date - TO_DATE('01/01/1970', 'DD/MM/YYYY'));
RETURN l_number * 86400000;
END oracle_to_unix;
FUNCTION unix_to_oracle (p_unix IN NUMBER) RETURN DATE AS
BEGIN
RETURN TO_DATE('01/01/1970', 'DD/MM/YYYY') + (p_unix * 86400000);
END unix_to_oracle;
END date_api;
/
SHOW ERRORS

View File

@@ -0,0 +1,23 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/dict_comments.sql
-- Author : Tim Hall
-- Description : Displays comments associate with specific tables.
-- Requirements : Access to the DBA views.
-- Call Syntax : @dict_comments (table-name or partial match)
-- Last Modified: 15/07/2000
-- -----------------------------------------------------------------------------------
PROMPT
SET VERIFY OFF
SET FEEDBACK OFF
SET LINESIZE 255
SET PAGESIZE 1000
SELECT a.table_name "Table",
Substr(a.comments,1,200) "Comments"
FROM dictionary a
WHERE a.table_name LIKE Upper('%&1%');
SET VERIFY ON
SET FEEDBACK ON
SET PAGESIZE 14
PROMPT

View File

@@ -0,0 +1,319 @@
CREATE OR REPLACE PACKAGE digest_auth_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/digest_auth_api.sql
-- Author : Tim Hall
-- Description : API to allow digest authentication when using UTL_HTTP.
-- The aim is this only replaces UTL_HTTP.BEGIN_REQUEST.
-- All other coding (wallet handling and processing the response)
-- are still done by you, in the normal way.
--
-- References : This is heavily inspired by the blog post by Gary Myers.
-- http://blog.sydoracle.com/2014/03/plsql-utlhttp-and-digest-authentication.html
-- I make liberal use of the ideas, and in some cases the code, he discussed in
-- that blog post!
-- For setting up certificates and wallets, see this article.
-- https://oracle-base.com/articles/misc/utl_http-and-ssl
--
-- License : Free for personal and commercial use.
-- You can amend the code, but leave existing the headers, current
-- amendments history and links intact.
-- Copyright and disclaimer available here:
-- https://oracle-base.com/misc/site-info.php#copyright
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 11-DEC-2015 Tim Hall Initial Creation
-- 30-JUN-2016 Tim Hall Add debug_on and debug_off procedures.
-- --------------------------------------------------------------------------
/*
Example call.
SET SERVEROUTPUT ON
DECLARE
l_url VARCHAR2(32767) := 'https://example.com/ws/get-something';
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_text VARCHAR2(32767);
BEGIN
-- Set wallet credentials.
UTL_HTTP.set_wallet('file:/path/to/wallet', 'wallet-password');
-- Make a HTTP request and get the response.
l_http_request := digest_auth_api.begin_request(p_url => l_url,
p_username => 'my-username',
p_password => 'my-password',
p_method => 'GET');
l_http_response := UTL_HTTP.get_response(l_http_request);
-- Loop through the response.
BEGIN
LOOP
UTL_HTTP.read_text(l_http_response, l_text, 32767);
DBMS_OUTPUT.put_line (l_text);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body THEN
UTL_HTTP.end_response(l_http_response);
END;
EXCEPTION
WHEN OTHERS THEN
UTL_HTTP.end_response(l_http_response);
RAISE;
END;
*/
-- --------------------------------------------------------------------------
PROCEDURE debug_on;
PROCEDURE debug_off;
FUNCTION begin_request(p_url IN VARCHAR2,
p_username IN VARCHAR2,
p_password IN VARCHAR2,
p_method IN VARCHAR2 DEFAULT 'GET',
p_http_version IN VARCHAR2 DEFAULT 'HTTP/1.1',
p_req_cnt IN PLS_INTEGER DEFAULT 1)
RETURN UTL_HTTP.req;
END digest_auth_api;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY digest_auth_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/digest_auth_api.sql
-- Author : Tim Hall
-- Description : API to allow digest authentication when using UTL_HTTP.
-- The aim is this only replaces UTL_HTTP.BEGIN_REQUEST.
-- All other coding (wallet handling and processing the response)
-- are still done by you, in the normal way.
--
-- References : This is heavily inspired by the blog post by Gary Myers.
-- http://blog.sydoracle.com/2014/03/plsql-utlhttp-and-digest-authentication.html
-- I make liberal use of the ideas, and in some cases the code, he discussed in
-- that blog post!
-- For setting up certificates and wallets, see this article.
-- https://oracle-base.com/articles/misc/utl_http-and-ssl
--
-- License : Free for personal and commercial use.
-- You can amend the code, but leave existing the headers, current
-- amendments history and links intact.
-- Copyright and disclaimer available here:
-- https://oracle-base.com/misc/site-info.php#copyright
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 11-DEC-2015 Tim Hall Initial Creation
-- 30-JUN-2016 Tim Hall Add debug_on and debug_off procedures.
-- --------------------------------------------------------------------------
-- Package variables.
g_debug BOOLEAN := FALSE;
-- Set by call to get_header_info.
g_server VARCHAR2(32767);
g_realm VARCHAR2(32767);
g_qop VARCHAR2(32767);
g_nonce VARCHAR2(32767);
g_opaque VARCHAR2(32767);
g_cnonce VARCHAR2(32767);
-- Prototypes.
PROCEDURE debug (p_text IN VARCHAR2);
PROCEDURE init;
PROCEDURE get_header_info (p_http_response IN OUT NOCOPY UTL_HTTP.resp);
FUNCTION get_response (p_username IN VARCHAR2,
p_password IN VARCHAR2,
p_uri IN VARCHAR2,
p_method IN VARCHAR2 DEFAULT 'GET',
p_req_cnt IN NUMBER DEFAULT 1)
RETURN VARCHAR2;
-- Real stuff starts here.
-- -----------------------------------------------------------------------------
PROCEDURE debug_on AS
BEGIN
g_debug := TRUE;
END debug_on;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
PROCEDURE debug_off AS
BEGIN
g_debug := FALSE;
END debug_off;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
PROCEDURE debug (p_text IN VARCHAR2) AS
BEGIN
IF g_debug THEN
DBMS_OUTPUT.put_line(p_text);
END IF;
END debug;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
PROCEDURE init IS
BEGIN
g_server := NULL;
g_realm := NULL;
g_qop := NULL;
g_nonce := NULL;
g_opaque := NULL;
g_cnonce := NULL;
END init;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
PROCEDURE get_header_info (p_http_response IN OUT NOCOPY UTL_HTTP.resp) IS
l_name VARCHAR2(256);
l_value VARCHAR2(1024);
BEGIN
FOR i IN 1..UTL_HTTP.get_header_count(p_http_response) LOOP
UTL_HTTP.get_header(p_http_response, i, l_name, l_value);
debug('------ Header (' || i || ') ------');
debug('l_name=' || l_name);
debug('l_value=' || l_value);
IF l_name = 'Server' THEN
g_server := l_value;
debug('g_server=' || g_server);
END IF;
IF l_name = 'WWW-Authenticate' THEN
g_realm := SUBSTR(REGEXP_SUBSTR(l_value, 'realm="[^"]+' ),8);
g_qop := SUBSTR(REGEXP_SUBSTR(l_value, 'qop="[^"]+' ),6);
g_nonce := SUBSTR(REGEXP_SUBSTR(l_value, 'nonce="[^"]+' ),8);
g_opaque := SUBSTR(REGEXP_SUBSTR(l_value, 'opaque="[^"]+'),9);
debug('g_realm=' || g_realm);
debug('g_qop=' || g_qop);
debug('g_nonce=' || g_nonce);
debug('g_opaque=' || g_opaque);
END IF;
END LOOP;
g_cnonce := LOWER(UTL_RAW.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.md5(input_string => DBMS_RANDOM.value)));
debug('g_cnonce=' || g_cnonce);
END get_header_info;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
FUNCTION get_response (p_username IN VARCHAR2,
p_password IN VARCHAR2,
p_uri IN VARCHAR2,
p_method IN VARCHAR2 DEFAULT 'GET',
p_req_cnt IN NUMBER DEFAULT 1)
RETURN VARCHAR2 IS
l_text VARCHAR2(2000);
l_raw RAW(2000);
l_out VARCHAR2(60);
l_ha1 VARCHAR2(40);
l_ha2 VARCHAR2(40);
BEGIN
l_text := p_username || ':' || g_realm || ':' || p_password;
l_raw := UTL_RAW.cast_to_raw(l_text);
l_out := DBMS_OBFUSCATION_TOOLKIT.md5(input => l_raw);
l_ha1 := LOWER(l_out);
l_text := p_method || ':' || p_uri;
l_raw := UTL_RAW.cast_to_raw(l_text);
l_out := DBMS_OBFUSCATION_TOOLKIT.md5(input => l_raw);
l_ha2 := LOWER(l_out);
l_text := l_ha1 || ':' || g_nonce || ':' || LPAD(p_req_cnt,8,0) || ':' || g_cnonce || ':' || g_qop || ':' || l_ha2;
l_raw := UTL_RAW.cast_to_raw(l_text);
l_out := DBMS_OBFUSCATION_TOOLKIT.md5(input => l_raw);
RETURN LOWER(l_out);
END get_response;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
FUNCTION begin_request(p_url IN VARCHAR2,
p_username IN VARCHAR2,
p_password IN VARCHAR2,
p_method IN VARCHAR2 DEFAULT 'GET',
p_http_version IN VARCHAR2 DEFAULT 'HTTP/1.1',
p_req_cnt IN PLS_INTEGER DEFAULT 1)
RETURN UTL_HTTP.req
AS
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_text VARCHAR2(32767);
l_uri VARCHAR2(32767);
l_response VARCHAR2(32767);
BEGIN
init;
-- Make a request that will fail to get the header information.
-- This will be used to build up the pieces for the digest authentication
-- using a call to get_header_info.
l_http_request := UTL_HTTP.begin_request(p_url, p_method);
l_http_response := UTL_HTTP.get_response(l_http_request);
get_header_info (l_http_response);
UTL_HTTP.end_response(l_http_response);
-- Get everything after the domain as the URI.
l_uri := SUBSTR(p_url, INSTR(p_url, '/', 1, 3));
l_response := get_response(p_username => p_username,
p_password => p_password,
p_uri => l_uri,
p_method => p_method,
p_req_cnt => p_req_cnt);
-- Build the final digest string.
l_text := 'Digest username="' || p_username ||'",'||
' realm="' || g_realm ||'",'||
' nonce="' || g_nonce ||'",'||
' uri="' || l_uri ||'",'||
' response="' || l_response ||'",'||
' qop=' || g_qop ||',' ||
' nc=' || LPAD(p_req_cnt,8,0) ||',' ||
' cnonce="' || g_cnonce ||'"';
IF g_opaque IS NOT NULL THEN
l_text := l_text || ',opaque="'||g_opaque||'"';
END IF;
debug(l_text);
-- Make the new request and set the digest authorization.
l_http_request := UTL_HTTP.begin_request(p_url, p_method);
UTL_HTTP.SET_HEADER(l_http_request, 'Authorization', l_text);
RETURN l_http_request;
EXCEPTION
WHEN OTHERS THEN
UTL_HTTP.end_response(l_http_response);
RAISE;
END begin_request;
-- -----------------------------------------------------------------------------
END digest_auth_api;
/
SHOW ERRORS

View File

@@ -0,0 +1,39 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/drop_all.sql
-- Author : Tim Hall
-- Description : Drops all objects within the current schema.
-- Call Syntax : @drop_all
-- Last Modified: 20/01/2006
-- Notes : Loops a maximum of 5 times, allowing for failed drops due to dependencies.
-- Quits outer loop if no drops were atempted.
-- -----------------------------------------------------------------------------------
SET SERVEROUTPUT ON
DECLARE
l_count NUMBER;
l_cascade VARCHAR2(20);
BEGIN
<< dependency_failure_loop >>
FOR i IN 1 .. 5 LOOP
EXIT dependency_failure_loop WHEN l_count = 0;
l_count := 0;
FOR cur_rec IN (SELECT object_name, object_type
FROM user_objects) LOOP
BEGIN
l_count := l_count + 1;
l_cascade := NULL;
IF cur_rec.object_type = 'TABLE' THEN
l_cascade := ' CASCADE CONSTRAINTS';
END IF;
EXECUTE IMMEDIATE 'DROP ' || cur_rec.object_type || ' "' || cur_rec.object_name || '"' || l_cascade;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END LOOP;
-- Comment out the following line if you are pre-10g, or want to preserve the recyclebin contents.
EXECUTE IMMEDIATE 'PURGE RECYCLEBIN';
DBMS_OUTPUT.put_line('Pass: ' || i || ' Drops: ' || l_count);
END LOOP;
END;
/

View File

@@ -0,0 +1,463 @@
CREATE OR REPLACE PACKAGE BODY dsp AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/dsp.pkb
-- Author : Tim Hall
-- Description : An extension of the DBMS_OUTPUT package.
-- Requirements : https://oracle-base.com/dba/miscellaneous/dsp.pks
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 08-JAN-2002 Tim Hall Initial Creation.
-- 04-APR-2005 Tim Hall Store last call. Add get_last_prefix and
-- get_last_data to allow retrieval.
-- Switch from date to timestamp for greater accuracy.
-- 01-MAR-2013 Tim Hall Add RAISE to output procedure.
-- Force upper case on directory object names.
-- 02-MAR-2013 Tim Hall Fix wrap_line. ORA-21780: Maximum number of object durations exceeded.
-- Added file_contents pipelined table function.
-- Added delete_file.
-- 02-DEC-2013 Tim Hall Add p_trace_level parameter to most code to
-- limit amount of trace produced.
-- Prefixed UTL_FILE references with "SYS.".
-- 21-NOV-2018 Tim Hall Add CLOB overloads to LINE.
-- --------------------------------------------------------------------------
-- Package Variables
g_show_output BOOLEAN := FALSE;
g_show_date BOOLEAN := FALSE;
g_line_wrap BOOLEAN := TRUE;
g_max_width PLS_INTEGER := 255;
g_date_format VARCHAR2(32767) := 'DD-MON-YYYY HH24:MI:SS.FF';
g_file_dir VARCHAR2(32767) := NULL;
g_file_name VARCHAR2(32767) := NULL;
g_last_prefix VARCHAR2(32767) := NULL;
g_last_data VARCHAR2(32767) := NULL;
g_trace_level PLS_INTEGER := DSP.trace_level_all;
-- Hidden Methods
PROCEDURE display (p_prefix IN VARCHAR2,
p_data IN VARCHAR2,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info,
p_wrap IN BOOLEAN := FALSE);
PROCEDURE display_clob (p_prefix IN VARCHAR2,
p_data IN CLOB,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE wrap_line (p_data IN VARCHAR2,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE wrap_line_clob (p_data IN CLOB,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE output (p_data IN VARCHAR2);
-- Exposed Methods
-- --------------------------------------------------------------------------
PROCEDURE reset_defaults IS
-- --------------------------------------------------------------------------
BEGIN
g_show_output := FALSE;
g_show_date := FALSE;
g_line_wrap := TRUE;
g_max_width := 255;
g_date_format := 'DD-MON-YYYY HH24:MI:SS.FF';
g_trace_level := DSP.trace_level_all;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE show_output_on(p_trace_level IN PLS_INTEGER := DSP.trace_level_all) IS
-- --------------------------------------------------------------------------
BEGIN
g_show_output := TRUE;
g_trace_level := p_trace_level;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE show_output_off IS
-- --------------------------------------------------------------------------
BEGIN
g_show_output := FALSE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE show_date_on IS
-- --------------------------------------------------------------------------
BEGIN
g_show_date := TRUE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE show_date_off IS
-- --------------------------------------------------------------------------
BEGIN
g_show_date := FALSE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line_wrap_on IS
-- --------------------------------------------------------------------------
BEGIN
g_line_wrap := TRUE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line_wrap_off IS
-- --------------------------------------------------------------------------
BEGIN
g_line_wrap := FALSE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE set_max_width (p_width IN PLS_INTEGER) IS
-- --------------------------------------------------------------------------
BEGIN
g_max_width := p_width;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE set_date_format (p_date_format IN VARCHAR2) IS
-- --------------------------------------------------------------------------
BEGIN
g_date_format := p_date_format;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE file_output_on (p_file_dir IN VARCHAR2 DEFAULT NULL,
p_file_name IN VARCHAR2 DEFAULT NULL) IS
-- --------------------------------------------------------------------------
BEGIN
g_file_dir := UPPER(p_file_dir);
g_file_name := p_file_name;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE file_output_off IS
-- --------------------------------------------------------------------------
BEGIN
g_file_dir := NULL;
g_file_name := NULL;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION get_last_prefix
RETURN VARCHAR2 IS
-- --------------------------------------------------------------------------
BEGIN
RETURN g_last_prefix;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION get_last_data
RETURN VARCHAR2 IS
-- --------------------------------------------------------------------------
BEGIN
RETURN g_last_data;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_data IN VARCHAR2,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
display (NULL, p_data, p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_data IN CLOB,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
display_clob (NULL, p_data, p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_data IN NUMBER,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
display (NULL, p_data, p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_data IN BOOLEAN,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
line (NULL, p_data, p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_data IN DATE,
p_format IN VARCHAR2 DEFAULT 'DD-MON-YYYY HH24:MI:SS.FF',
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
line (NULL, p_data, p_format, p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN VARCHAR2,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
display (p_prefix, p_data, p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN CLOB,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
display_clob (p_prefix, p_data, p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN NUMBER,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
display (p_prefix, TO_CHAR(p_data), p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN BOOLEAN,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
IF p_data THEN
display (p_prefix, 'TRUE', p_trace_level);
ELSE
display (p_prefix, 'FALSE', p_trace_level);
END IF;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN DATE,
p_format IN VARCHAR2 DEFAULT 'DD-MON-YYYY HH24:MI:SS.FF',
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
BEGIN
display (p_prefix, TO_CHAR(p_data, p_format), p_trace_level);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE display (p_prefix IN VARCHAR2,
p_data IN VARCHAR2,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info,
p_wrap IN BOOLEAN := FALSE) IS
-- --------------------------------------------------------------------------
l_data VARCHAR2(32767) := p_data;
BEGIN
g_last_prefix := p_prefix;
g_last_data := p_data;
IF g_show_output AND p_trace_level <= g_trace_level THEN
IF l_data IS NULL THEN
l_data := '<NULL>';
END IF;
IF p_prefix IS NOT NULL AND p_wrap = FALSE THEN
l_data := p_prefix || ' : ' || l_data;
END IF;
IF g_show_date AND p_wrap = FALSE THEN
l_data := TO_CHAR(SYSTIMESTAMP, g_date_format) || ' : ' || l_data;
END IF;
IF LENGTH(l_data) > g_max_width THEN
IF g_line_wrap THEN
wrap_line (l_data);
ELSE
l_data := SUBSTR(l_data, 1, g_max_width);
output (l_data);
END IF;
ELSE
output (l_data);
END IF;
END IF;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE display_clob (p_prefix IN VARCHAR2,
p_data IN CLOB,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
l_data CLOB := p_data;
BEGIN
g_last_prefix := p_prefix;
IF g_show_output AND p_trace_level <= g_trace_level THEN
IF l_data IS NULL THEN
l_data := '<NULL>';
END IF;
IF p_prefix IS NOT NULL THEN
l_data := p_prefix || ' : ' || l_data;
END IF;
IF g_show_date THEN
l_data := TO_CHAR(SYSTIMESTAMP, g_date_format) || ' : ' || l_data;
END IF;
wrap_line_clob (l_data);
END IF;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE wrap_line (p_data IN VARCHAR2,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
l_offset NUMBER := 1;
BEGIN
LOOP
EXIT WHEN l_offset > LENGTH(p_data);
display (NULL, SUBSTR(p_data, l_offset, g_max_width), p_trace_level, TRUE);
l_offset := l_offset + g_max_width;
END LOOP;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE wrap_line_clob (p_data IN CLOB,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info) IS
-- --------------------------------------------------------------------------
l_offset NUMBER := 1;
BEGIN
LOOP
EXIT WHEN l_offset > LENGTH(p_data);
display (NULL, SUBSTR(p_data, l_offset, g_max_width), p_trace_level, TRUE);
l_offset := l_offset + g_max_width;
END LOOP;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE output (p_data IN VARCHAR2) IS
-- --------------------------------------------------------------------------
BEGIN
IF g_file_dir IS NULL OR g_file_name IS NULL THEN
DBMS_OUTPUT.put_line(p_data);
ELSE
DECLARE
l_file SYS.UTL_FILE.file_type;
BEGIN
l_file := SYS.UTL_FILE.fopen (g_file_dir, g_file_name, 'A', 32767);
SYS.UTL_FILE.put_line(l_file, p_data);
SYS.UTL_FILE.fclose (l_file);
EXCEPTION
WHEN OTHERS THEN
SYS.UTL_FILE.fclose (l_file);
RAISE;
END;
END IF;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION file_contents (p_dir IN VARCHAR2,
p_file IN VARCHAR2)
RETURN DBMSOUTPUT_LINESARRAY PIPELINED IS
-- --------------------------------------------------------------------------
l_file SYS.UTL_FILE.file_type;
l_text VARCHAR2(32767);
BEGIN
l_file := SYS.UTL_FILE.fopen(UPPER(p_dir), p_file, 'r', 32767);
BEGIN
LOOP
SYS.UTL_FILE.get_line(l_file, l_text);
PIPE ROW (l_text);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
END;
UTL_FILE.fclose(l_file);
RETURN;
EXCEPTION
WHEN OTHERS THEN
PIPE ROW ('ERROR: ' || SQLERRM);
IF SYS.UTL_FILE.is_open(l_file) THEN
SYS.UTL_FILE.fclose(l_file);
END IF;
RETURN;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE delete_file (p_dir IN VARCHAR2,
p_file IN VARCHAR2) IS
-- --------------------------------------------------------------------------
BEGIN
SYS.UTL_FILE.fremove(UPPER(p_dir), p_file);
END;
-- --------------------------------------------------------------------------
END dsp;
/
SHOW ERRORS

View File

@@ -0,0 +1,128 @@
CREATE OR REPLACE PACKAGE dsp AUTHID CURRENT_USER AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/dsp.pks
-- Author : Tim Hall
-- Description : An extension of the DBMS_OUTPUT package.
-- Requirements : https://oracle-base.com/dba/miscellaneous/dsp.pkb
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 08-JAN-2002 Tim Hall Initial Creation
-- 04-APR-2005 Tim Hall Store last call. Add get_last_prefix and
-- get_last_data to allow retrieval.
-- Switch from date to timestamp for greater accuracy.
-- 02-MAR-2013 Tim Hall Added file_contents pipelined table function.
-- Added delete_file.
-- Added example usage comments.
-- 02-DEC-2013 Tim Hall Add p_trace_level parameter to most code to
-- limit amount of trace produced.
-- Added "AUTHID CURRENT_USER".
-- 21-NOV-2018 Tim Hall Add CLOB overloads to LINE.
-- --------------------------------------------------------------------------
-- Example usage :
/*
-- Set up test directory object.
CREATE OR REPLACE DIRECTORY test_dir AS '/home/oracle/';
GRANT READ, WRITE ON DIRECTORY test_dir TO test;
-- Test DSP.
BEGIN
-- Turn on tracing, redirecting it to a file.
DSP.show_output_on;
DSP.file_output_on('TEST_DIR', 'test.txt');
DSP.show_date_on;
DSP.line_wrap_on;
DSP.set_max_width(200);
-- Trace something.
DSP.line('This is a test');
END;
-- Check the contents of the file.
SELECT * FROM TABLE(DSP.file_contents('TEST_DIR', 'test.txt'));
-- Delete the file.
EXEC DSP.delete_file('TEST_DIR', 'test.txt');
*/
-- --------------------------------------------------------------------------
-- Constants to control tracing level.
trace_level_all CONSTANT PLS_INTEGER := 99;
trace_level_info CONSTANT PLS_INTEGER := 30;
trace_level_warn CONSTANT PLS_INTEGER := 20;
trace_level_error CONSTANT PLS_INTEGER := 10;
PROCEDURE reset_defaults;
PROCEDURE show_output_on(p_trace_level IN PLS_INTEGER := DSP.trace_level_all);
PROCEDURE show_output_off;
PROCEDURE show_date_on;
PROCEDURE show_date_off;
PROCEDURE line_wrap_on;
PROCEDURE line_wrap_off;
PROCEDURE set_max_width (p_width IN PLS_INTEGER);
PROCEDURE set_date_format (p_date_format IN VARCHAR2);
PROCEDURE file_output_on (p_file_dir IN VARCHAR2 DEFAULT NULL,
p_file_name IN VARCHAR2 DEFAULT NULL);
PROCEDURE file_output_off;
FUNCTION get_last_prefix
RETURN VARCHAR2;
FUNCTION get_last_data
RETURN VARCHAR2;
PROCEDURE line (p_data IN VARCHAR2,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_data IN CLOB,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_data IN NUMBER,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_data IN BOOLEAN,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_data IN DATE,
p_format IN VARCHAR2 DEFAULT 'DD-MON-YYYY HH24:MI:SS.FF',
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN VARCHAR2,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN CLOB,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN NUMBER,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN BOOLEAN,
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN DATE,
p_format IN VARCHAR2 DEFAULT 'DD-MON-YYYY HH24:MI:SS.FF',
p_trace_level IN PLS_INTEGER := DSP.trace_level_info);
FUNCTION file_contents (p_dir IN VARCHAR2,
p_file IN VARCHAR2)
RETURN DBMSOUTPUT_LINESARRAY PIPELINED;
PROCEDURE delete_file (p_dir IN VARCHAR2,
p_file IN VARCHAR2);
END dsp;
/
SHOW ERRORS

View File

@@ -0,0 +1,126 @@
CREATE OR REPLACE PACKAGE BODY err AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/err.pkb
-- Author : Tim Hall
-- Description : A simple mechanism for logging error information to a table.
-- Requirements : err.pks, dsp.pks, dsp.pkb and schema definied in err.pks
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 17-JUL-2003 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
-- Package Variables
g_logs_on BOOLEAN := TRUE;
g_date_format VARCHAR2(50) := 'DD-MON-YYYY HH24:MI:SS';
-- Exposed Methods
-- --------------------------------------------------------------------------
PROCEDURE reset_defaults IS
-- --------------------------------------------------------------------------
BEGIN
g_logs_on := TRUE;
g_date_format := 'DD-MON-YYYY HH24:MI:SS';
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE logs_on IS
-- --------------------------------------------------------------------------
BEGIN
g_logs_on := TRUE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE logs_off IS
-- --------------------------------------------------------------------------
BEGIN
g_logs_on := FALSE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE set_date_format (p_date_format IN VARCHAR2 DEFAULT 'DD-MON-YYYY HH24:MI:SS') IS
-- --------------------------------------------------------------------------
BEGIN
g_date_format := p_date_format;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN VARCHAR2,
p_error_level IN NUMBER DEFAULT 5,
p_error_user IN VARCHAR2 DEFAULT USER) IS
-- --------------------------------------------------------------------------
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF g_logs_on THEN
INSERT INTO error_logs
(id,
prefix,
data,
error_level,
created_date,
created_by)
VALUES
(error_logs_seq.NEXTVAL,
p_prefix,
p_data,
p_error_level,
SYSDATE,
p_error_user);
COMMIT;
END IF;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_data IN VARCHAR2,
p_error_level IN NUMBER DEFAULT 5,
p_error_user IN VARCHAR2 DEFAULT USER) IS
-- --------------------------------------------------------------------------
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
line (p_prefix => NULL,
p_data => p_data,
p_error_level => p_error_level,
p_error_user => p_error_user);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE display (p_error_level IN NUMBER DEFAULT NULL,
p_error_user IN VARCHAR2 DEFAULT NULL,
p_from_date IN DATE DEFAULT NULL,
p_to_date IN DATE DEFAULT NUll) IS
-- --------------------------------------------------------------------------
CURSOR c_errors IS
SELECT *
FROM error_logs
WHERE error_level = NVL(p_error_level, error_level)
AND created_by = NVL(p_error_user, created_by)
AND created_date >= NVL(p_from_date, created_date)
AND created_date <= NVL(p_to_date, created_date)
ORDER BY id;
BEGIN
FOR cur_rec IN c_errors LOOP
dsp.line(cur_rec.prefix, cur_rec.data);
END LOOP;
END;
-- --------------------------------------------------------------------------
END err;
/
SHOW ERRORS

View File

@@ -0,0 +1,50 @@
CREATE OR REPLACE PACKAGE err AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/err.pks
-- Author : Tim Hall
-- Description : A simple mechanism for logging error information to a table.
-- Requirements : err.pkb, dsp.pks, dsp.pkb and:
--
-- CREATE TABLE error_logs (
-- id NUMBER(10) NOT NULL,
-- prefix VARCHAR2(50),
-- data VARCHAR2(2000) NOT NULL,
-- error_level NUMBER(2) NOT NULL,
-- created_date DATE NOT NULL,
-- created_by VARCHAR2(50) NOT NULL);
--
-- ALTER TABLE error_logs ADD (CONSTRAINT error_logs_pk PRIMARY KEY (id));
--
-- CREATE SEQUENCE error_logs_seq;
--
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 17-JUL-2003 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
PROCEDURE reset_defaults;
PROCEDURE logs_on;
PROCEDURE logs_off;
PROCEDURE set_date_format (p_date_format IN VARCHAR2 DEFAULT 'DD-MON-YYYY HH24:MI:SS');
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN VARCHAR2,
p_error_level IN NUMBER DEFAULT 5,
p_error_user IN VARCHAR2 DEFAULT USER);
PROCEDURE line (p_data IN VARCHAR2,
p_error_level IN NUMBER DEFAULT 5,
p_error_user IN VARCHAR2 DEFAULT USER);
PROCEDURE display (p_error_level IN NUMBER DEFAULT NULL,
p_error_user IN VARCHAR2 DEFAULT NULL,
p_from_date IN DATE DEFAULT NULL,
p_to_date IN DATE DEFAULT NUll);
END err;
/
SHOW ERRORS

View File

@@ -0,0 +1,29 @@
CREATE OR REPLACE PROCEDURE file_to_blob (p_blob IN OUT NOCOPY BLOB,
p_dir IN VARCHAR2,
p_filename IN VARCHAR2)
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/file_to_blob.sql
-- Author : Tim Hall
-- Description : Loads the contents of a file into a BLOB.
-- Last Modified: 26/02/2019 - Taken from 2005 article.
-- -----------------------------------------------------------------------------------
AS
l_bfile BFILE;
l_dest_offset INTEGER := 1;
l_src_offset INTEGER := 1;
BEGIN
l_bfile := BFILENAME(p_dir, p_filename);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
DBMS_LOB.trim(p_blob, 0);
IF DBMS_LOB.getlength(l_bfile) > 0 THEN
DBMS_LOB.loadblobfromfile (
dest_lob => p_blob,
src_bfile => l_bfile,
amount => DBMS_LOB.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset);
END IF;
DBMS_LOB.fileclose(l_bfile);
END file_to_blob;
/

View File

@@ -0,0 +1,33 @@
CREATE OR REPLACE PROCEDURE file_to_clob (p_clob IN OUT NOCOPY CLOB,
p_dir IN VARCHAR2,
p_filename IN VARCHAR2)
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/file_to_clob.sql
-- Author : Tim Hall
-- Description : Loads the contents of a file into a CLOB.
-- Last Modified: 26/02/2019 - Taken from 2005 article.
-- -----------------------------------------------------------------------------------
AS
l_bfile BFILE;
l_dest_offset INTEGER := 1;
l_src_offset INTEGER := 1;
l_bfile_csid NUMBER := 0;
l_lang_context INTEGER := 0;
l_warning INTEGER := 0;
BEGIN
l_bfile := BFILENAME(p_dir, p_filename);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
DBMS_LOB.trim(p_clob, 0);
DBMS_LOB.loadclobfromfile (
dest_lob => p_clob,
src_bfile => l_bfile,
amount => DBMS_LOB.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset,
bfile_csid => l_bfile_csid ,
lang_context => l_lang_context,
warning => l_warning);
DBMS_LOB.fileclose(l_bfile);
END file_to_clob;
/

View File

@@ -0,0 +1,18 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/find_object.sql
-- Author : Tim Hall
-- Description : Lists all objects with a similar name to that specified.
-- Requirements : Access to the DBA views.
-- Call Syntax : @find_object (object-name)
-- Last Modified: 26-JUL-2016
-- -----------------------------------------------------------------------------------
SET VERIFY OFF LINESIZE 200
COLUMN object_name FORMAT A30
COLUMN owner FORMAT A20
SELECT object_name, owner, object_type, status
FROM dba_objects
WHERE LOWER(object_name) LIKE '%' || LOWER('&1') || '%'
ORDER BY 1, 2, 3;

View File

@@ -0,0 +1,839 @@
CREATE OR REPLACE PACKAGE BODY ftp AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/ftp.pkb
-- Author : Tim Hall
-- Description : Basic FTP API. For usage notes see:
-- https://oracle-base.com/articles/misc/ftp-from-plsql.php
-- Requirements : https://oracle-base.com/dba/miscellaneous/ftp.pks
-- License : Free for personal and commercial use.
-- You can amend the code, but leave existing the headers, current
-- amendments history and links intact.
-- Copyright and disclaimer available here:
-- https://oracle-base.com/misc/site-info.php#copyright
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 14-AUG-2003 Tim Hall Initial Creation
-- 10-MAR-2004 Tim Hall Add convert_crlf procedure.
-- Incorporate CRLF conversion functionality into
-- put_local_ascii_data and put_remote_ascii_data
-- functions.
-- Make get_passive function visible.
-- Added get_direct and put_direct procedures.
-- 23-DEC-2004 Tim Hall The get_reply procedure was altered to deal with
-- banners starting with 4 white spaces. This fix is
-- a small variation on the resolution provided by
-- Gary Mason who spotted the bug.
-- 10-NOV-2005 Tim Hall Addition of get_reply after doing a transfer to
-- pickup the 226 Transfer complete message. This
-- allows gets and puts with a single connection.
-- Issue spotted by Trevor Woolnough.
-- 03-OCT-2006 Tim Hall Add list, rename, delete, mkdir, rmdir procedures.
-- 12-JAN-2007 Tim Hall A final call to get_reply was added to the get_remote%
-- procedures to allow multiple transfers per connection.
-- 15-Jan-2008 Tim Hall login: Include timeout parameter (suggested by Dmitry Bogomolov).
-- 21-Jan-2008 Tim Hall put_%: "l_pos < l_clob_len" to "l_pos <= l_clob_len" to prevent
-- potential loss of one character for single-byte files or files
-- sized 1 byte bigger than a number divisible by the buffer size
-- (spotted by Michael Surikov).
-- 23-Jan-2008 Tim Hall send_command: Possible solution for ORA-29260 errors included,
-- but commented out (suggested by Kevin Phillips).
-- 12-Feb-2008 Tim Hall put_local_binary_data and put_direct: Open file with "wb" for
-- binary writes (spotted by Dwayne Hoban).
-- 03-Mar-2008 Tim Hall list: get_reply call and close of passive connection added
-- (suggested by Julian, Bavaria).
-- 12-Jun-2008 Tim Hall A final call to get_reply was added to the put_remote%
-- procedures, but commented out. If uncommented, it may cause the
-- operation to hang, but it has been reported (morgul) to allow
-- multiple transfers per connection.
-- get_reply: Moved to pakage specification.
-- 24-Jun-2008 Tim Hall get_remote% and put_remote%: Exception handler added to close the passive
-- connection and reraise the error (suggested by Mark Reichman).
-- 22-Apr-2009 Tim Hall get_remote_ascii_data: Remove unnecessary logout (suggested by John Duncan).
-- get_reply and list: Handle 400 messages as well as 500 messages (suggested by John Duncan).
-- logout: Added a call to UTL_TCP.close_connection, so not necessary to close
-- any connections manually (suggested by Victor Munoz).
-- get_local_*_data: Check for zero length files to prevent exception (suggested by Daniel)
-- nlst: Added to return list of file names only (suggested by Julian and John Duncan)
-- 05-Apr-2011 Tim Hall put_remote_ascii_data: Added comment on definition of l_amount. Switch to 10000 if you get
-- ORA-06502 from this line. May give you unexpected result due to conversion. Better to use binary.
-- 05-Oct-2013 Tim Hall list, nlst: Fixed bug where files beginning with '4' or '5' could cause error.
-- 24-May-2014 Tim Hall Added license information.
-- 09-Feb-2015 Tim Hall get_passive: Removed reference to IP address (suggested by Dinesh Panwar).
-- 01-Oct-2016 Tim Hall All 32767 buffers altered to 32766 to prevent errors with some
-- multibyte character set operations (suggested by jdziurlaj).
-- 24-Oct-2016 Tim Hall Removed passive connections for mkdir, rmdir, rename, delete (suggested by Dirk).
-- 22-Jan-2017 Tim Hall Added UTL_TCP.close_connection for passive connections to exception handlers for
-- get_direct, put_direct, list, nlst (Peter Renner).
-- 05-Jan-2018 Tim Hall get_local_ascii_data : Switch from LOADFROMFILE to LOADCLOBFROMFILE.
-- get_local_binary_data : Switch from LOADFROMFILE to LOADBLOBFROMFILE.
-- (suggested by Stephen Skene)
-- --------------------------------------------------------------------------
g_reply t_string_table := t_string_table();
g_binary BOOLEAN := TRUE;
g_debug BOOLEAN := TRUE;
g_convert_crlf BOOLEAN := TRUE;
PROCEDURE debug (p_text IN VARCHAR2);
-- --------------------------------------------------------------------------
FUNCTION login (p_host IN VARCHAR2,
p_port IN VARCHAR2,
p_user IN VARCHAR2,
p_pass IN VARCHAR2,
p_timeout IN NUMBER := NULL)
RETURN UTL_TCP.connection IS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
BEGIN
g_reply.delete;
l_conn := UTL_TCP.open_connection(p_host, p_port, tx_timeout => p_timeout);
get_reply (l_conn);
send_command(l_conn, 'USER ' || p_user);
send_command(l_conn, 'PASS ' || p_pass);
RETURN l_conn;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION get_passive (p_conn IN OUT NOCOPY UTL_TCP.connection)
RETURN UTL_TCP.connection IS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_reply VARCHAR2(32766);
--l_host VARCHAR(100);
l_port1 NUMBER(10);
l_port2 NUMBER(10);
BEGIN
send_command(p_conn, 'PASV');
l_reply := g_reply(g_reply.last);
l_reply := REPLACE(SUBSTR(l_reply, INSTR(l_reply, '(') + 1, (INSTR(l_reply, ')')) - (INSTR(l_reply, '('))-1), ',', '.');
--l_host := SUBSTR(l_reply, 1, INSTR(l_reply, '.', 1, 4)-1);
l_port1 := TO_NUMBER(SUBSTR(l_reply, INSTR(l_reply, '.', 1, 4)+1, (INSTR(l_reply, '.', 1, 5)-1) - (INSTR(l_reply, '.', 1, 4))));
l_port2 := TO_NUMBER(SUBSTR(l_reply, INSTR(l_reply, '.', 1, 5)+1));
--l_conn := utl_tcp.open_connection(l_host, 256 * l_port1 + l_port2);
l_conn := utl_tcp.open_connection(p_conn.remote_host, 256 * l_port1 + l_port2);
return l_conn;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE logout(p_conn IN OUT NOCOPY UTL_TCP.connection,
p_reply IN BOOLEAN := TRUE) AS
-- --------------------------------------------------------------------------
BEGIN
send_command(p_conn, 'QUIT', p_reply);
UTL_TCP.close_connection(p_conn);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE send_command (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_command IN VARCHAR2,
p_reply IN BOOLEAN := TRUE) IS
-- --------------------------------------------------------------------------
l_result PLS_INTEGER;
BEGIN
l_result := UTL_TCP.write_line(p_conn, p_command);
-- If you get ORA-29260 after the PASV call, replace the above line with the following line.
-- l_result := UTL_TCP.write_text(p_conn, p_command || utl_tcp.crlf, length(p_command || utl_tcp.crlf));
IF p_reply THEN
get_reply(p_conn);
END IF;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE get_reply (p_conn IN OUT NOCOPY UTL_TCP.connection) IS
-- --------------------------------------------------------------------------
l_reply_code VARCHAR2(3) := NULL;
BEGIN
LOOP
g_reply.extend;
g_reply(g_reply.last) := UTL_TCP.get_line(p_conn, TRUE);
debug(g_reply(g_reply.last));
IF l_reply_code IS NULL THEN
l_reply_code := SUBSTR(g_reply(g_reply.last), 1, 3);
END IF;
IF SUBSTR(l_reply_code, 1, 1) IN ('4', '5') THEN
RAISE_APPLICATION_ERROR(-20000, g_reply(g_reply.last));
ELSIF (SUBSTR(g_reply(g_reply.last), 1, 3) = l_reply_code AND
SUBSTR(g_reply(g_reply.last), 4, 1) = ' ') THEN
EXIT;
END IF;
END LOOP;
EXCEPTION
WHEN UTL_TCP.END_OF_INPUT THEN
NULL;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION get_local_ascii_data (p_dir IN VARCHAR2,
p_file IN VARCHAR2)
RETURN CLOB IS
-- --------------------------------------------------------------------------
l_bfile BFILE;
l_data CLOB;
l_dest_offset INTEGER := 1;
l_src_offset INTEGER := 1;
l_bfile_csid NUMBER := 0;
l_lang_context INTEGER := 0;
l_warning INTEGER := 0;
BEGIN
DBMS_LOB.createtemporary (lob_loc => l_data,
cache => TRUE,
dur => DBMS_LOB.call);
l_bfile := BFILENAME(p_dir, p_file);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
IF DBMS_LOB.getlength(l_bfile) > 0 THEN
DBMS_LOB.loadclobfromfile (
dest_lob => l_data,
src_bfile => l_bfile,
amount => DBMS_LOB.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset,
bfile_csid => l_bfile_csid ,
lang_context => l_lang_context,
warning => l_warning);
END IF;
DBMS_LOB.fileclose(l_bfile);
RETURN l_data;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION get_local_binary_data (p_dir IN VARCHAR2,
p_file IN VARCHAR2)
RETURN BLOB IS
-- --------------------------------------------------------------------------
l_bfile BFILE;
l_data BLOB;
l_dest_offset INTEGER := 1;
l_src_offset INTEGER := 1;
BEGIN
DBMS_LOB.createtemporary (lob_loc => l_data,
cache => TRUE,
dur => DBMS_LOB.call);
l_bfile := BFILENAME(p_dir, p_file);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
IF DBMS_LOB.getlength(l_bfile) > 0 THEN
DBMS_LOB.loadblobfromfile (
dest_lob => l_data,
src_bfile => l_bfile,
amount => DBMS_LOB.lobmaxsize,
dest_offset => l_dest_offset,
src_offset => l_src_offset);
END IF;
DBMS_LOB.fileclose(l_bfile);
RETURN l_data;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION get_remote_ascii_data (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2)
RETURN CLOB IS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_amount PLS_INTEGER;
l_buffer VARCHAR2(32766);
l_data CLOB;
BEGIN
DBMS_LOB.createtemporary (lob_loc => l_data,
cache => TRUE,
dur => DBMS_LOB.call);
l_conn := get_passive(p_conn);
send_command(p_conn, 'RETR ' || p_file, TRUE);
--logout(l_conn, FALSE);
BEGIN
LOOP
l_amount := UTL_TCP.read_text (l_conn, l_buffer, 32766);
DBMS_LOB.writeappend(l_data, l_amount, l_buffer);
END LOOP;
EXCEPTION
WHEN UTL_TCP.END_OF_INPUT THEN
NULL;
WHEN OTHERS THEN
NULL;
END;
UTL_TCP.close_connection(l_conn);
get_reply(p_conn);
RETURN l_data;
EXCEPTION
WHEN OTHERS THEN
UTL_TCP.close_connection(l_conn);
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION get_remote_binary_data (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2)
RETURN BLOB IS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_amount PLS_INTEGER;
l_buffer RAW(32766);
l_data BLOB;
BEGIN
DBMS_LOB.createtemporary (lob_loc => l_data,
cache => TRUE,
dur => DBMS_LOB.call);
l_conn := get_passive(p_conn);
send_command(p_conn, 'RETR ' || p_file, TRUE);
BEGIN
LOOP
l_amount := UTL_TCP.read_raw (l_conn, l_buffer, 32766);
DBMS_LOB.writeappend(l_data, l_amount, l_buffer);
END LOOP;
EXCEPTION
WHEN UTL_TCP.END_OF_INPUT THEN
NULL;
WHEN OTHERS THEN
NULL;
END;
UTL_TCP.close_connection(l_conn);
get_reply(p_conn);
RETURN l_data;
EXCEPTION
WHEN OTHERS THEN
UTL_TCP.close_connection(l_conn);
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE put_local_ascii_data (p_data IN CLOB,
p_dir IN VARCHAR2,
p_file IN VARCHAR2) IS
-- --------------------------------------------------------------------------
l_out_file UTL_FILE.file_type;
l_buffer VARCHAR2(32766);
l_amount BINARY_INTEGER := 32766;
l_pos INTEGER := 1;
l_clob_len INTEGER;
BEGIN
l_clob_len := DBMS_LOB.getlength(p_data);
l_out_file := UTL_FILE.fopen(p_dir, p_file, 'w', 32766);
WHILE l_pos <= l_clob_len LOOP
DBMS_LOB.read (p_data, l_amount, l_pos, l_buffer);
IF g_convert_crlf THEN
l_buffer := REPLACE(l_buffer, CHR(13), NULL);
END IF;
UTL_FILE.put(l_out_file, l_buffer);
UTL_FILE.fflush(l_out_file);
l_pos := l_pos + l_amount;
END LOOP;
UTL_FILE.fclose(l_out_file);
EXCEPTION
WHEN OTHERS THEN
IF UTL_FILE.is_open(l_out_file) THEN
UTL_FILE.fclose(l_out_file);
END IF;
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE put_local_binary_data (p_data IN BLOB,
p_dir IN VARCHAR2,
p_file IN VARCHAR2) IS
-- --------------------------------------------------------------------------
l_out_file UTL_FILE.file_type;
l_buffer RAW(32766);
l_amount BINARY_INTEGER := 32766;
l_pos INTEGER := 1;
l_blob_len INTEGER;
BEGIN
l_blob_len := DBMS_LOB.getlength(p_data);
l_out_file := UTL_FILE.fopen(p_dir, p_file, 'wb', 32766);
WHILE l_pos <= l_blob_len LOOP
DBMS_LOB.read (p_data, l_amount, l_pos, l_buffer);
UTL_FILE.put_raw(l_out_file, l_buffer, TRUE);
UTL_FILE.fflush(l_out_file);
l_pos := l_pos + l_amount;
END LOOP;
UTL_FILE.fclose(l_out_file);
EXCEPTION
WHEN OTHERS THEN
IF UTL_FILE.is_open(l_out_file) THEN
UTL_FILE.fclose(l_out_file);
END IF;
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE put_remote_ascii_data (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2,
p_data IN CLOB) IS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_result PLS_INTEGER;
l_buffer VARCHAR2(32766);
l_amount BINARY_INTEGER := 32766; -- Switch to 10000 (or use binary) if you get ORA-06502 from this line.
l_pos INTEGER := 1;
l_clob_len INTEGER;
BEGIN
l_conn := get_passive(p_conn);
send_command(p_conn, 'STOR ' || p_file, TRUE);
l_clob_len := DBMS_LOB.getlength(p_data);
WHILE l_pos <= l_clob_len LOOP
DBMS_LOB.READ (p_data, l_amount, l_pos, l_buffer);
IF g_convert_crlf THEN
l_buffer := REPLACE(l_buffer, CHR(13), NULL);
END IF;
l_result := UTL_TCP.write_text(l_conn, l_buffer, LENGTH(l_buffer));
UTL_TCP.flush(l_conn);
l_pos := l_pos + l_amount;
END LOOP;
UTL_TCP.close_connection(l_conn);
-- The following line allows some people to make multiple calls from one connection.
-- It causes the operation to hang for me, hence it is commented out by default.
-- get_reply(p_conn);
EXCEPTION
WHEN OTHERS THEN
UTL_TCP.close_connection(l_conn);
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE put_remote_binary_data (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2,
p_data IN BLOB) IS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_result PLS_INTEGER;
l_buffer RAW(32766);
l_amount BINARY_INTEGER := 32766;
l_pos INTEGER := 1;
l_blob_len INTEGER;
BEGIN
l_conn := get_passive(p_conn);
send_command(p_conn, 'STOR ' || p_file, TRUE);
l_blob_len := DBMS_LOB.getlength(p_data);
WHILE l_pos <= l_blob_len LOOP
DBMS_LOB.READ (p_data, l_amount, l_pos, l_buffer);
l_result := UTL_TCP.write_raw(l_conn, l_buffer, l_amount);
UTL_TCP.flush(l_conn);
l_pos := l_pos + l_amount;
END LOOP;
UTL_TCP.close_connection(l_conn);
-- The following line allows some people to make multiple calls from one connection.
-- It causes the operation to hang for me, hence it is commented out by default.
-- get_reply(p_conn);
EXCEPTION
WHEN OTHERS THEN
UTL_TCP.close_connection(l_conn);
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE get (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from_file IN VARCHAR2,
p_to_dir IN VARCHAR2,
p_to_file IN VARCHAR2) AS
-- --------------------------------------------------------------------------
BEGIN
IF g_binary THEN
put_local_binary_data(p_data => get_remote_binary_data (p_conn, p_from_file),
p_dir => p_to_dir,
p_file => p_to_file);
ELSE
put_local_ascii_data(p_data => get_remote_ascii_data (p_conn, p_from_file),
p_dir => p_to_dir,
p_file => p_to_file);
END IF;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE put (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from_dir IN VARCHAR2,
p_from_file IN VARCHAR2,
p_to_file IN VARCHAR2) AS
-- --------------------------------------------------------------------------
BEGIN
IF g_binary THEN
put_remote_binary_data(p_conn => p_conn,
p_file => p_to_file,
p_data => get_local_binary_data(p_from_dir, p_from_file));
ELSE
put_remote_ascii_data(p_conn => p_conn,
p_file => p_to_file,
p_data => get_local_ascii_data(p_from_dir, p_from_file));
END IF;
get_reply(p_conn);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE get_direct (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from_file IN VARCHAR2,
p_to_dir IN VARCHAR2,
p_to_file IN VARCHAR2) IS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_out_file UTL_FILE.file_type;
l_amount PLS_INTEGER;
l_buffer VARCHAR2(32766);
l_raw_buffer RAW(32766);
BEGIN
l_conn := get_passive(p_conn);
send_command(p_conn, 'RETR ' || p_from_file, TRUE);
IF g_binary THEN
l_out_file := UTL_FILE.fopen(p_to_dir, p_to_file, 'wb', 32766);
ELSE
l_out_file := UTL_FILE.fopen(p_to_dir, p_to_file, 'w', 32766);
END IF;
BEGIN
LOOP
IF g_binary THEN
l_amount := UTL_TCP.read_raw (l_conn, l_raw_buffer, 32766);
UTL_FILE.put_raw(l_out_file, l_raw_buffer, TRUE);
ELSE
l_amount := UTL_TCP.read_text (l_conn, l_buffer, 32766);
IF g_convert_crlf THEN
l_buffer := REPLACE(l_buffer, CHR(13), NULL);
END IF;
UTL_FILE.put(l_out_file, l_buffer);
END IF;
UTL_FILE.fflush(l_out_file);
END LOOP;
EXCEPTION
WHEN UTL_TCP.END_OF_INPUT THEN
NULL;
WHEN OTHERS THEN
NULL;
END;
UTL_FILE.fclose(l_out_file);
UTL_TCP.close_connection(l_conn);
EXCEPTION
WHEN OTHERS THEN
UTL_TCP.close_connection(l_conn);
IF UTL_FILE.is_open(l_out_file) THEN
UTL_FILE.fclose(l_out_file);
END IF;
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE put_direct (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from_dir IN VARCHAR2,
p_from_file IN VARCHAR2,
p_to_file IN VARCHAR2) IS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_bfile BFILE;
l_result PLS_INTEGER;
l_amount PLS_INTEGER := 32766;
l_raw_buffer RAW(32766);
l_len NUMBER;
l_pos NUMBER := 1;
ex_ascii EXCEPTION;
BEGIN
IF NOT g_binary THEN
RAISE ex_ascii;
END IF;
l_conn := get_passive(p_conn);
send_command(p_conn, 'STOR ' || p_to_file, TRUE);
l_bfile := BFILENAME(p_from_dir, p_from_file);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
l_len := DBMS_LOB.getlength(l_bfile);
WHILE l_pos <= l_len LOOP
DBMS_LOB.READ (l_bfile, l_amount, l_pos, l_raw_buffer);
debug(l_amount);
l_result := UTL_TCP.write_raw(l_conn, l_raw_buffer, l_amount);
l_pos := l_pos + l_amount;
END LOOP;
DBMS_LOB.fileclose(l_bfile);
UTL_TCP.close_connection(l_conn);
EXCEPTION
WHEN ex_ascii THEN
UTL_TCP.close_connection(l_conn);
RAISE_APPLICATION_ERROR(-20000, 'PUT_DIRECT not available in ASCII mode.');
WHEN OTHERS THEN
UTL_TCP.close_connection(l_conn);
IF DBMS_LOB.fileisopen(l_bfile) = 1 THEN
DBMS_LOB.fileclose(l_bfile);
END IF;
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE help (p_conn IN OUT NOCOPY UTL_TCP.connection) AS
-- --------------------------------------------------------------------------
BEGIN
send_command(p_conn, 'HELP', TRUE);
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE ascii (p_conn IN OUT NOCOPY UTL_TCP.connection) AS
-- --------------------------------------------------------------------------
BEGIN
send_command(p_conn, 'TYPE A', TRUE);
g_binary := FALSE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE binary (p_conn IN OUT NOCOPY UTL_TCP.connection) AS
-- --------------------------------------------------------------------------
BEGIN
send_command(p_conn, 'TYPE I', TRUE);
g_binary := TRUE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE list (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_dir IN VARCHAR2,
p_list OUT t_string_table) AS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_list t_string_table := t_string_table();
l_reply_code VARCHAR2(3) := NULL;
BEGIN
l_conn := get_passive(p_conn);
send_command(p_conn, 'LIST ' || p_dir, TRUE);
BEGIN
LOOP
l_list.extend;
l_list(l_list.last) := UTL_TCP.get_line(l_conn, TRUE);
debug(l_list(l_list.last));
IF l_reply_code IS NULL THEN
l_reply_code := SUBSTR(l_list(l_list.last), 1, 3);
END IF;
IF (SUBSTR(l_reply_code, 1, 1) IN ('4', '5') AND
SUBSTR(l_reply_code, 4, 1) = ' ') THEN
RAISE_APPLICATION_ERROR(-20000, l_list(l_list.last));
ELSIF (SUBSTR(g_reply(g_reply.last), 1, 3) = l_reply_code AND
SUBSTR(g_reply(g_reply.last), 4, 1) = ' ') THEN
EXIT;
END IF;
END LOOP;
EXCEPTION
WHEN UTL_TCP.END_OF_INPUT THEN
NULL;
END;
l_list.delete(l_list.last);
p_list := l_list;
utl_tcp.close_connection(l_conn);
get_reply (p_conn);
EXCEPTION
WHEN OTHERS THEN
UTL_TCP.close_connection(l_conn);
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE nlst (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_dir IN VARCHAR2,
p_list OUT t_string_table) AS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
l_list t_string_table := t_string_table();
l_reply_code VARCHAR2(3) := NULL;
BEGIN
l_conn := get_passive(p_conn);
send_command(p_conn, 'NLST ' || p_dir, TRUE);
BEGIN
LOOP
l_list.extend;
l_list(l_list.last) := UTL_TCP.get_line(l_conn, TRUE);
debug(l_list(l_list.last));
IF l_reply_code IS NULL THEN
l_reply_code := SUBSTR(l_list(l_list.last), 1, 3);
END IF;
IF (SUBSTR(l_reply_code, 1, 1) IN ('4', '5') AND
SUBSTR(l_reply_code, 4, 1) = ' ') THEN
RAISE_APPLICATION_ERROR(-20000, l_list(l_list.last));
ELSIF (SUBSTR(g_reply(g_reply.last), 1, 3) = l_reply_code AND
SUBSTR(g_reply(g_reply.last), 4, 1) = ' ') THEN
EXIT;
END IF;
END LOOP;
EXCEPTION
WHEN UTL_TCP.END_OF_INPUT THEN
NULL;
END;
l_list.delete(l_list.last);
p_list := l_list;
utl_tcp.close_connection(l_conn);
get_reply (p_conn);
EXCEPTION
WHEN OTHERS THEN
UTL_TCP.close_connection(l_conn);
RAISE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE rename (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from IN VARCHAR2,
p_to IN VARCHAR2) AS
-- --------------------------------------------------------------------------
l_conn UTL_TCP.connection;
BEGIN
send_command(p_conn, 'RNFR ' || p_from, TRUE);
send_command(p_conn, 'RNTO ' || p_to, TRUE);
END rename;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE delete (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2) AS
-- --------------------------------------------------------------------------
BEGIN
send_command(p_conn, 'DELE ' || p_file, TRUE);
END delete;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE mkdir (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_dir IN VARCHAR2) AS
-- --------------------------------------------------------------------------
BEGIN
send_command(p_conn, 'MKD ' || p_dir, TRUE);
END mkdir;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE rmdir (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_dir IN VARCHAR2) AS
-- --------------------------------------------------------------------------
BEGIN
send_command(p_conn, 'RMD ' || p_dir, TRUE);
END rmdir;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE convert_crlf (p_status IN BOOLEAN) AS
-- --------------------------------------------------------------------------
BEGIN
g_convert_crlf := p_status;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE debug (p_text IN VARCHAR2) IS
-- --------------------------------------------------------------------------
BEGIN
IF g_debug THEN
DBMS_OUTPUT.put_line(SUBSTR(p_text, 1, 255));
END IF;
END;
-- --------------------------------------------------------------------------
END ftp;
/
SHOW ERRORS

View File

@@ -0,0 +1,131 @@
CREATE OR REPLACE PACKAGE ftp AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/ftp.pks
-- Author : Tim Hall
-- Description : Basic FTP API. For usage notes see:
-- https://oracle-base.com/articles/misc/ftp-from-plsql.php
-- Requirements : UTL_TCP
-- License : Free for personal and commercial use.
-- You can amend the code, but leave existing the headers, current
-- amendments history and links intact.
-- Copyright and disclaimer available here:
-- https://oracle-base.com/misc/site-info.php#copyright
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 14-AUG-2003 Tim Hall Initial Creation
-- 10-MAR-2004 Tim Hall Add convert_crlf procedure.
-- Make get_passive function visible.
-- Added get_direct and put_direct procedures.
-- 03-OCT-2006 Tim Hall Add list, rename, delete, mkdir, rmdir procedures.
-- 15-Jan-2008 Tim Hall login: Include timeout parameter (suggested by Dmitry Bogomolov).
-- 12-Jun-2008 Tim Hall get_reply: Moved to pakage specification.
-- 22-Apr-2009 Tim Hall nlst: Added to return list of file names only (suggested by Julian and John Duncan)
-- 24-May-2014 Tim Hall Added license information.
-- --------------------------------------------------------------------------
TYPE t_string_table IS TABLE OF VARCHAR2(32767);
FUNCTION login (p_host IN VARCHAR2,
p_port IN VARCHAR2,
p_user IN VARCHAR2,
p_pass IN VARCHAR2,
p_timeout IN NUMBER := NULL)
RETURN UTL_TCP.connection;
FUNCTION get_passive (p_conn IN OUT NOCOPY UTL_TCP.connection)
RETURN UTL_TCP.connection;
PROCEDURE logout (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_reply IN BOOLEAN := TRUE);
PROCEDURE send_command (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_command IN VARCHAR2,
p_reply IN BOOLEAN := TRUE);
PROCEDURE get_reply (p_conn IN OUT NOCOPY UTL_TCP.connection);
FUNCTION get_local_ascii_data (p_dir IN VARCHAR2,
p_file IN VARCHAR2)
RETURN CLOB;
FUNCTION get_local_binary_data (p_dir IN VARCHAR2,
p_file IN VARCHAR2)
RETURN BLOB;
FUNCTION get_remote_ascii_data (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2)
RETURN CLOB;
FUNCTION get_remote_binary_data (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2)
RETURN BLOB;
PROCEDURE put_local_ascii_data (p_data IN CLOB,
p_dir IN VARCHAR2,
p_file IN VARCHAR2);
PROCEDURE put_local_binary_data (p_data IN BLOB,
p_dir IN VARCHAR2,
p_file IN VARCHAR2);
PROCEDURE put_remote_ascii_data (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2,
p_data IN CLOB);
PROCEDURE put_remote_binary_data (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2,
p_data IN BLOB);
PROCEDURE get (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from_file IN VARCHAR2,
p_to_dir IN VARCHAR2,
p_to_file IN VARCHAR2);
PROCEDURE put (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from_dir IN VARCHAR2,
p_from_file IN VARCHAR2,
p_to_file IN VARCHAR2);
PROCEDURE get_direct (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from_file IN VARCHAR2,
p_to_dir IN VARCHAR2,
p_to_file IN VARCHAR2);
PROCEDURE put_direct (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from_dir IN VARCHAR2,
p_from_file IN VARCHAR2,
p_to_file IN VARCHAR2);
PROCEDURE help (p_conn IN OUT NOCOPY UTL_TCP.connection);
PROCEDURE ascii (p_conn IN OUT NOCOPY UTL_TCP.connection);
PROCEDURE binary (p_conn IN OUT NOCOPY UTL_TCP.connection);
PROCEDURE list (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_dir IN VARCHAR2,
p_list OUT t_string_table);
PROCEDURE nlst (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_dir IN VARCHAR2,
p_list OUT t_string_table);
PROCEDURE rename (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_from IN VARCHAR2,
p_to IN VARCHAR2);
PROCEDURE delete (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_file IN VARCHAR2);
PROCEDURE mkdir (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_dir IN VARCHAR2);
PROCEDURE rmdir (p_conn IN OUT NOCOPY UTL_TCP.connection,
p_dir IN VARCHAR2);
PROCEDURE convert_crlf (p_status IN BOOLEAN);
END ftp;
/
SHOW ERRORS

View File

@@ -0,0 +1,40 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/gen_health.sql
-- Author : Tim Hall
-- Description : Miscellaneous queries to check the general health of the system.
-- Call Syntax : @gen_health
-- Last Modified: 15/07/2000
-- -----------------------------------------------------------------------------------
SELECT file_id,
tablespace_name,
file_name,
status
FROM sys.dba_data_files;
SELECT file#,
name,
status,
enabled
FROM v$datafile;
SELECT *
FROM v$backup;
SELECT *
FROM v$recovery_status;
SELECT *
FROM v$recover_file;
SELECT *
FROM v$recovery_file_status;
SELECT *
FROM v$recovery_log;
SELECT username,
command,
status,
module
FROM v$session;

View File

@@ -0,0 +1,29 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/get_pivot.sql
-- Author : Tim Hall
-- Description : Creates a function to produce a virtual pivot table with the specific values.
-- Requirements : CREATE TYPE, CREATE PROCEDURE
-- Call Syntax : @get_pivot.sql
-- Last Modified: 13/08/2003
-- -----------------------------------------------------------------------------------
CREATE OR REPLACE TYPE t_pivot AS TABLE OF NUMBER;
/
CREATE OR REPLACE FUNCTION get_pivot(p_max IN NUMBER,
p_step IN NUMBER DEFAULT 1)
RETURN t_pivot AS
l_pivot t_pivot := t_pivot();
BEGIN
FOR i IN 0 .. TRUNC(p_max/p_step) LOOP
l_pivot.extend;
l_pivot(l_pivot.last) := 1 + (i * p_step);
END LOOP;
RETURN l_pivot;
END;
/
SHOW ERRORS
SELECT column_value
FROM TABLE(get_pivot(17,2));

View File

@@ -0,0 +1,32 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/get_stat.sql
-- Author : Tim Hall
-- Description : A function to return the specified statistic value.
-- Requirements : Select on V_$MYSTAT and V_$STATNAME.
-- Call Syntax : Example of checking the amount of PGA memory allocated.
--
-- DECLARE
-- l_start NUMBER;
-- BEGIN
-- l_start := get_stat('session pga memory');
--
-- -- Do something.
--
-- DBMS_OUTPUT.put_line('PGA Memory Allocated : ' || (get_stat('session pga memory') - g_start) || ' bytes');
-- END;
-- /
--
-- Last Modified: 05/03/2018
-- -----------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION get_stat (p_stat IN VARCHAR2) RETURN NUMBER AS
l_return NUMBER;
BEGIN
SELECT ms.value
INTO l_return
FROM v$mystat ms,
v$statname sn
WHERE ms.statistic# = sn.statistic#
AND sn.name = p_stat;
RETURN l_return;
END get_stat;
/

View File

@@ -0,0 +1,23 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/login.sql
-- Author : Tim Hall
-- Description : Resets the SQL*Plus prompt when a new connection is made.
-- Call Syntax : @login
-- Last Modified: 04/03/2004
-- -----------------------------------------------------------------------------------
SET FEEDBACK OFF
SET TERMOUT OFF
COLUMN X NEW_VALUE Y
SELECT LOWER(USER || '@' || SYS_CONTEXT('userenv', 'instance_name')) X FROM dual;
SET SQLPROMPT '&Y> '
ALTER SESSION SET NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT='DD-MON-YYYY HH24:MI:SS.FF';
SET TERMOUT ON
SET FEEDBACK ON
SET LINESIZE 100
SET TAB OFF
SET TRIM ON
SET TRIMSPOOL ON

View File

@@ -0,0 +1,34 @@
CREATE OR REPLACE FUNCTION part_hv_to_date (p_table_owner IN VARCHAR2,
p_table_name IN VARCHAR2,
p_partition_name IN VARCHAR2)
RETURN DATE
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/part_hv_to_date.sql
-- Author : Tim Hall
-- Description : Create a function to turn partition HIGH_VALUE column to a date.
-- Call Syntax : @part_hv_to_date
-- Last Modified: 19/01/2012
-- Notes : Has to re-select the value from the view as LONG cannot be passed as a parameter.
-- Example call:
--
-- SELECT a.partition_name,
-- part_hv_to_date(a.table_owner, a.table_name, a.partition_name) as high_value
-- FROM all_tab_partitions a;
--
-- Does no error handling.
-- -----------------------------------------------------------------------------------
AS
l_high_value VARCHAR2(32767);
l_date DATE;
BEGIN
SELECT high_value
INTO l_high_value
FROM all_tab_partitions
WHERE table_owner = p_table_owner
AND table_name = p_table_name
AND partition_name = p_partition_name;
EXECUTE IMMEDIATE 'SELECT ' || l_high_value || ' FROM dual' INTO l_date;
RETURN l_date;
END;
/

View File

@@ -0,0 +1,39 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/proc_defs.sql
-- Author : Tim Hall
-- Description : Lists the parameters for the specified package and procedure.
-- Call Syntax : @proc_defs (package-name) (procedure-name or all)
-- Last Modified: 24/09/2003
-- -----------------------------------------------------------------------------------
COLUMN "Object Name" FORMAT A30
COLUMN ol FORMAT A2
COLUMN sq FORMAT 99
COLUMN "Argument Name" FORMAT A32
COLUMN "Type" FORMAT A15
COLUMN "Size" FORMAT A6
BREAK ON ol SKIP 2
SET PAGESIZE 0
SET LINESIZE 200
SET TRIMOUT ON
SET TRIMSPOOL ON
SET VERIFY OFF
SELECT object_name AS "Object Name",
overload AS ol,
sequence AS sq,
RPAD(' ', data_level*2, ' ') || argument_name AS "Argument Name",
data_type AS "Type",
(CASE
WHEN data_type IN ('VARCHAR2','CHAR') THEN TO_CHAR(data_length)
WHEN data_scale IS NULL OR data_scale = 0 THEN TO_CHAR(data_precision)
ELSE TO_CHAR(data_precision) || ',' || TO_CHAR(data_scale)
END) "Size",
in_out AS "In/Out",
default_value
FROM user_arguments
WHERE package_name = UPPER('&1')
AND object_name = DECODE(UPPER('&2'), 'ALL', object_name, UPPER('&2'))
ORDER BY object_name, overload, sequence;
SET PAGESIZE 14
SET LINESIZE 80

View File

@@ -0,0 +1,28 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/rebuild_index.sql
-- Author : Tim Hall
-- Description : Rebuilds the specified index, or all indexes.
-- Call Syntax : @rebuild_index (index-name or all) (schema-name)
-- Last Modified: 28/01/2001
-- -----------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER INDEX ' || a.index_name || ' REBUILD;'
FROM all_indexes a
WHERE index_name = DECODE(Upper('&1'),'ALL',a.index_name,Upper('&1'))
AND table_owner = Upper('&2')
ORDER BY 1
/
SPOOL OFF
-- Comment out following line to prevent immediate run
@temp.sql
SET PAGESIZE 14
SET FEEDBACK ON
SET VERIFY ON

View File

@@ -0,0 +1,213 @@
CREATE OR REPLACE PACKAGE smart_quotes_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/smart_quotes_api.sql
-- Author : Tim Hall
-- Description : Routines to help deal with smart quotes..
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 07-JUN-2017 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
FUNCTION contains_smart_quote_bool (p_clob IN CLOB) RETURN BOOLEAN;
FUNCTION contains_smart_quote_bool (p_text IN VARCHAR2) RETURN BOOLEAN;
FUNCTION contains_smart_quote_num (p_clob IN CLOB) RETURN NUMBER;
FUNCTION contains_smart_quote_num (p_text IN VARCHAR2) RETURN NUMBER;
PROCEDURE remove_smart_quotes (p_clob IN OUT NOCOPY CLOB);
PROCEDURE remove_smart_quotes (p_text IN OUT VARCHAR2);
FUNCTION remove_smart_quotes (p_clob IN CLOB) RETURN CLOB;
FUNCTION remove_smart_quotes (p_text IN VARCHAR2) RETURN VARCHAR2;
END smart_quotes_api;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY smart_quotes_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/smart_quotes_api.sql
-- Author : Tim Hall
-- Description : Routines to help deal with smart quotes..
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 07-JUN-2017 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
TYPE t_sq_arr IS TABLE OF VARCHAR2(10)
INDEX BY VARCHAR2 (10);
g_sq_arr t_sq_arr;
-- --------------------------------------------------------------------------
FUNCTION contains_smart_quote_bool (p_clob IN CLOB) RETURN BOOLEAN AS
l_idx VARCHAR2(10);
BEGIN
l_idx := g_sq_arr.FIRST;
WHILE l_idx IS NOT NULL LOOP
IF INSTR(p_clob, l_idx) > 0 THEN
RETURN TRUE;
END IF;
l_idx := g_sq_arr.NEXT(l_idx);
END LOOP display_loop;
RETURN FALSE;
END contains_smart_quote_bool;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION contains_smart_quote_bool (p_text IN VARCHAR2) RETURN BOOLEAN AS
l_idx VARCHAR2(10);
BEGIN
l_idx := g_sq_arr.FIRST;
WHILE l_idx IS NOT NULL LOOP
IF INSTR(p_text, l_idx) > 0 THEN
RETURN TRUE;
END IF;
l_idx := g_sq_arr.NEXT(l_idx);
END LOOP display_loop;
RETURN FALSE;
END contains_smart_quote_bool;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION contains_smart_quote_num (p_clob IN CLOB) RETURN NUMBER AS
BEGIN
IF contains_smart_quote_bool (p_clob => p_clob) = TRUE THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END contains_smart_quote_num;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION contains_smart_quote_num (p_text IN VARCHAR2) RETURN NUMBER AS
BEGIN
IF contains_smart_quote_bool (p_text => p_text) = TRUE THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END contains_smart_quote_num;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE remove_smart_quotes (p_clob IN OUT NOCOPY CLOB) AS
-- --------------------------------------------------------------------------
l_idx VARCHAR2(10);
BEGIN
l_idx := g_sq_arr.FIRST;
WHILE l_idx IS NOT NULL LOOP
p_clob := REPLACE(p_clob, l_idx, g_sq_arr(l_idx));
l_idx := g_sq_arr.NEXT(l_idx);
END LOOP display_loop;
END remove_smart_quotes;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE remove_smart_quotes (p_text IN OUT VARCHAR2) AS
-- --------------------------------------------------------------------------
l_idx VARCHAR2(10);
BEGIN
l_idx := g_sq_arr.FIRST;
WHILE l_idx IS NOT NULL LOOP
p_text := REPLACE(p_text, l_idx, g_sq_arr(l_idx));
l_idx := g_sq_arr.NEXT(l_idx);
END LOOP display_loop;
END remove_smart_quotes;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION remove_smart_quotes (p_clob IN CLOB) RETURN CLOB AS
-- --------------------------------------------------------------------------
l_clob CLOB;
BEGIN
l_clob := p_clob;
remove_smart_quotes (p_clob => l_clob);
RETURN l_clob;
END remove_smart_quotes;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
FUNCTION remove_smart_quotes (p_text IN VARCHAR2) RETURN VARCHAR2 AS
-- --------------------------------------------------------------------------
l_text VARCHAR2(32767);
BEGIN
l_text := p_text;
remove_smart_quotes (p_text => l_text);
RETURN l_text;
END remove_smart_quotes;
-- --------------------------------------------------------------------------
BEGIN
-- Initialise Array of Smart Quotes.
-- Array Index = Smart Quote.
-- Array Value = Replacement Value.
g_sq_arr(CHR(145)) := '''';
g_sq_arr(CHR(146)) := '''';
--g_sq_arr(CHR(8216)) := '''';
--g_sq_arr(CHR(8217)) := '''';
g_sq_arr(CHR(147)) := '"';
g_sq_arr(CHR(148)) := '"';
g_sq_arr(CHR(8220)) := '"';
g_sq_arr(CHR(8221)) := '"';
g_sq_arr(CHR(151)) := '--';
g_sq_arr(CHR(150)) := '-';
g_sq_arr(CHR(133)) := '...';
g_sq_arr(CHR(149)) := CHR(38)||'bull;';
g_sq_arr(CHR(49855)) := '-';
g_sq_arr(CHR(50578)) := CHR(38)||'OElig;';
g_sq_arr(CHR(50579)) := CHR(38)||'oelig;';
g_sq_arr(CHR(50592)) := 'S';
g_sq_arr(CHR(50593)) := 's';
g_sq_arr(CHR(50616)) := 'Y';
g_sq_arr(CHR(50834)) := 'f';
g_sq_arr(CHR(52102)) := '^';
g_sq_arr(CHR(52124)) := '~';
g_sq_arr(CHR(14844051)) := '-';
g_sq_arr(CHR(14844052)) := '-';
g_sq_arr(CHR(14844053)) := '-';
g_sq_arr(CHR(14844056)) := '''';
g_sq_arr(CHR(14844057)) := '''';
g_sq_arr(CHR(14844058)) := ',';
g_sq_arr(CHR(14844060)) := '"';
g_sq_arr(CHR(14844061)) := '"';
g_sq_arr(CHR(14844062)) := '"';
g_sq_arr(CHR(14844064)) := CHR(38)||'dagger;';
g_sq_arr(CHR(14844064)) := CHR(38)||'Dagger;';
g_sq_arr(CHR(14844066)) := '.';
g_sq_arr(CHR(14844070)) := '...';
g_sq_arr(CHR(14844080)) := CHR(38)||'permil;';
g_sq_arr(CHR(14844089)) := '<';
g_sq_arr(CHR(14844090)) := '>';
g_sq_arr(CHR(14845090)) := CHR(38)||'trade;';
END smart_quotes_api;
/
SHOW ERRORS

View File

@@ -0,0 +1,270 @@
CREATE OR REPLACE PACKAGE soap_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/soap_api.sql
-- Author : Tim Hall
-- Description : SOAP related functions for consuming web services.
-- License : Free for personal and commercial use.
-- You can amend the code, but leave existing the headers, current
-- amendments history and links intact.
-- Copyright and disclaimer available here:
-- https://oracle-base.com/misc/site-info.php#copyright
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 04-OCT-2003 Tim Hall Initial Creation
-- 23-FEB-2006 Tim Hall Parameterized the "soap" envelope tags.
-- 25-MAY-2012 Tim Hall Added debug switch.
-- 29-MAY-2012 Tim Hall Allow parameters to have no type definition.
-- Change the default envelope tag to "soap".
-- add_complex_parameter: Include parameter XML manually.
-- 24-MAY-2014 Tim Hall Added license information.
-- --------------------------------------------------------------------------
TYPE t_request IS RECORD (
method VARCHAR2(256),
namespace VARCHAR2(256),
body VARCHAR2(32767),
envelope_tag VARCHAR2(30)
);
TYPE t_response IS RECORD
(
doc XMLTYPE,
envelope_tag VARCHAR2(30)
);
FUNCTION new_request(p_method IN VARCHAR2,
p_namespace IN VARCHAR2,
p_envelope_tag IN VARCHAR2 DEFAULT 'soap')
RETURN t_request;
PROCEDURE add_parameter(p_request IN OUT NOCOPY t_request,
p_name IN VARCHAR2,
p_value IN VARCHAR2,
p_type IN VARCHAR2 := NULL);
PROCEDURE add_complex_parameter(p_request IN OUT NOCOPY t_request,
p_xml IN VARCHAR2);
FUNCTION invoke(p_request IN OUT NOCOPY t_request,
p_url IN VARCHAR2,
p_action IN VARCHAR2)
RETURN t_response;
FUNCTION get_return_value(p_response IN OUT NOCOPY t_response,
p_name IN VARCHAR2,
p_namespace IN VARCHAR2)
RETURN VARCHAR2;
PROCEDURE debug_on;
PROCEDURE debug_off;
END soap_api;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY soap_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/soap_api.sql
-- Author : Tim Hall
-- Description : SOAP related functions for consuming web services.
-- License : Free for personal and commercial use.
-- You can amend the code, but leave existing the headers, current
-- amendments history and links intact.
-- Copyright and disclaimer available here:
-- https://oracle-base.com/misc/site-info.php#copyright
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 04-OCT-2003 Tim Hall Initial Creation
-- 23-FEB-2006 Tim Hall Parameterized the "soap" envelope tags.
-- 25-MAY-2012 Tim Hall Added debug switch.
-- 29-MAY-2012 Tim Hall Allow parameters to have no type definition.
-- Change the default envelope tag to "soap".
-- add_complex_parameter: Include parameter XML manually.
-- 24-MAY-2014 Tim Hall Added license information.
-- --------------------------------------------------------------------------
g_debug BOOLEAN := FALSE;
PROCEDURE show_envelope(p_env IN VARCHAR2,
p_heading IN VARCHAR2 DEFAULT NULL);
-- ---------------------------------------------------------------------
FUNCTION new_request(p_method IN VARCHAR2,
p_namespace IN VARCHAR2,
p_envelope_tag IN VARCHAR2 DEFAULT 'soap')
RETURN t_request AS
-- ---------------------------------------------------------------------
l_request t_request;
BEGIN
l_request.method := p_method;
l_request.namespace := p_namespace;
l_request.envelope_tag := p_envelope_tag;
RETURN l_request;
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
PROCEDURE add_parameter(p_request IN OUT NOCOPY t_request,
p_name IN VARCHAR2,
p_value IN VARCHAR2,
p_type IN VARCHAR2 := NULL) AS
-- ---------------------------------------------------------------------
BEGIN
IF p_type IS NULL THEN
p_request.body := p_request.body||'<'||p_name||'>'||p_value||'</'||p_name||'>';
ELSE
p_request.body := p_request.body||'<'||p_name||' xsi:type="'||p_type||'">'||p_value||'</'||p_name||'>';
END IF;
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
PROCEDURE add_complex_parameter(p_request IN OUT NOCOPY t_request,
p_xml IN VARCHAR2) AS
-- ---------------------------------------------------------------------
BEGIN
p_request.body := p_request.body||p_xml;
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
PROCEDURE generate_envelope(p_request IN OUT NOCOPY t_request,
p_env IN OUT NOCOPY VARCHAR2) AS
-- ---------------------------------------------------------------------
BEGIN
p_env := '<'||p_request.envelope_tag||':Envelope xmlns:'||p_request.envelope_tag||'="http://schemas.xmlsoap.org/soap/envelope/" ' ||
'xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">' ||
'<'||p_request.envelope_tag||':Body>' ||
'<'||p_request.method||' '||p_request.namespace||' '||p_request.envelope_tag||':encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' ||
p_request.body ||
'</'||p_request.method||'>' ||
'</'||p_request.envelope_tag||':Body>' ||
'</'||p_request.envelope_tag||':Envelope>';
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
PROCEDURE show_envelope(p_env IN VARCHAR2,
p_heading IN VARCHAR2 DEFAULT NULL) AS
-- ---------------------------------------------------------------------
i PLS_INTEGER;
l_len PLS_INTEGER;
BEGIN
IF g_debug THEN
IF p_heading IS NOT NULL THEN
DBMS_OUTPUT.put_line('*****' || p_heading || '*****');
END IF;
i := 1; l_len := LENGTH(p_env);
WHILE (i <= l_len) LOOP
DBMS_OUTPUT.put_line(SUBSTR(p_env, i, 60));
i := i + 60;
END LOOP;
END IF;
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
PROCEDURE check_fault(p_response IN OUT NOCOPY t_response) AS
-- ---------------------------------------------------------------------
l_fault_node XMLTYPE;
l_fault_code VARCHAR2(256);
l_fault_string VARCHAR2(32767);
BEGIN
l_fault_node := p_response.doc.extract('/'||p_response.envelope_tag||':Fault',
'xmlns:'||p_response.envelope_tag||'="http://schemas.xmlsoap.org/soap/envelope/');
IF (l_fault_node IS NOT NULL) THEN
l_fault_code := l_fault_node.extract('/'||p_response.envelope_tag||':Fault/faultcode/child::text()',
'xmlns:'||p_response.envelope_tag||'="http://schemas.xmlsoap.org/soap/envelope/').getstringval();
l_fault_string := l_fault_node.extract('/'||p_response.envelope_tag||':Fault/faultstring/child::text()',
'xmlns:'||p_response.envelope_tag||'="http://schemas.xmlsoap.org/soap/envelope/').getstringval();
RAISE_APPLICATION_ERROR(-20000, l_fault_code || ' - ' || l_fault_string);
END IF;
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
FUNCTION invoke(p_request IN OUT NOCOPY t_request,
p_url IN VARCHAR2,
p_action IN VARCHAR2)
RETURN t_response AS
-- ---------------------------------------------------------------------
l_envelope VARCHAR2(32767);
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_response t_response;
BEGIN
generate_envelope(p_request, l_envelope);
show_envelope(l_envelope, 'Request');
l_http_request := UTL_HTTP.begin_request(p_url, 'POST','HTTP/1.1');
UTL_HTTP.set_header(l_http_request, 'Content-Type', 'text/xml');
UTL_HTTP.set_header(l_http_request, 'Content-Length', LENGTH(l_envelope));
UTL_HTTP.set_header(l_http_request, 'SOAPAction', p_action);
UTL_HTTP.write_text(l_http_request, l_envelope);
l_http_response := UTL_HTTP.get_response(l_http_request);
UTL_HTTP.read_text(l_http_response, l_envelope);
UTL_HTTP.end_response(l_http_response);
show_envelope(l_envelope, 'Response');
l_response.doc := XMLTYPE.createxml(l_envelope);
l_response.envelope_tag := p_request.envelope_tag;
l_response.doc := l_response.doc.extract('/'||l_response.envelope_tag||':Envelope/'||l_response.envelope_tag||':Body/child::node()',
'xmlns:'||l_response.envelope_tag||'="http://schemas.xmlsoap.org/soap/envelope/"');
check_fault(l_response);
RETURN l_response;
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
FUNCTION get_return_value(p_response IN OUT NOCOPY t_response,
p_name IN VARCHAR2,
p_namespace IN VARCHAR2)
RETURN VARCHAR2 AS
-- ---------------------------------------------------------------------
BEGIN
RETURN p_response.doc.extract('//'||p_name||'/child::text()',p_namespace).getstringval();
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
PROCEDURE debug_on AS
-- ---------------------------------------------------------------------
BEGIN
g_debug := TRUE;
END;
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
PROCEDURE debug_off AS
-- ---------------------------------------------------------------------
BEGIN
g_debug := FALSE;
END;
-- ---------------------------------------------------------------------
END soap_api;
/
SHOW ERRORS

View File

@@ -0,0 +1,87 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/string_agg.sql
-- Author : Tim Hall (based on an a method suggested by Tom Kyte).
-- http://asktom.oracle.com/pls/ask/f?p=4950:8:::::F4950_P8_DISPLAYID:229614022562
-- Description : Aggregate function to concatenate strings.
-- Call Syntax : Incorporate into queries as follows:
-- COLUMN employees FORMAT A50
--
-- SELECT deptno, string_agg(ename) AS employees
-- FROM emp
-- GROUP BY deptno;
--
-- DEPTNO EMPLOYEES
-- ---------- --------------------------------------------------
-- 10 CLARK,KING,MILLER
-- 20 SMITH,FORD,ADAMS,SCOTT,JONES
-- 30 ALLEN,BLAKE,MARTIN,TURNER,JAMES,WARD
--
-- Last Modified: 03-JAN-2018 : Correction to separator handling in ODCIAggregateTerminate
-- and ODCIAggregateMerge, suggested by Kim Berg Hansen.
-- -----------------------------------------------------------------------------------
CREATE OR REPLACE TYPE t_string_agg AS OBJECT
(
g_string VARCHAR2(32767),
STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT t_string_agg)
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_string_agg,
value IN VARCHAR2 )
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate(self IN t_string_agg,
returnValue OUT VARCHAR2,
flags IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_string_agg,
ctx2 IN t_string_agg)
RETURN NUMBER
);
/
SHOW ERRORS
CREATE OR REPLACE TYPE BODY t_string_agg IS
STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT t_string_agg)
RETURN NUMBER IS
BEGIN
sctx := t_string_agg(NULL);
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_string_agg,
value IN VARCHAR2 )
RETURN NUMBER IS
BEGIN
SELF.g_string := self.g_string || ',' || value;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateTerminate(self IN t_string_agg,
returnValue OUT VARCHAR2,
flags IN NUMBER)
RETURN NUMBER IS
BEGIN
returnValue := SUBSTR(SELF.g_string, 2);
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_string_agg,
ctx2 IN t_string_agg)
RETURN NUMBER IS
BEGIN
SELF.g_string := SELF.g_string || ctx2.g_string;
RETURN ODCIConst.Success;
END;
END;
/
SHOW ERRORS
CREATE OR REPLACE FUNCTION string_agg (p_input VARCHAR2)
RETURN VARCHAR2
PARALLEL_ENABLE AGGREGATE USING t_string_agg;
/
SHOW ERRORS

View File

@@ -0,0 +1,198 @@
CREATE OR REPLACE PACKAGE string_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/string_api.sql
-- Author : Tim Hall
-- Description : A package to hold string utilities.
-- Requirements :
-- Amendments :
-- When Who What
-- =========== ======== =================================================
-- 02-DEC-2004 Tim Hall Initial Creation
-- 19-JAN-2017 Tim Hall Add get_uri_paramter_value function.
-- --------------------------------------------------------------------------
-- Public types
TYPE t_split_array IS TABLE OF VARCHAR2(4000);
FUNCTION split_text (p_text IN CLOB,
p_delimeter IN VARCHAR2 DEFAULT ',')
RETURN t_split_array;
PROCEDURE print_clob (p_clob IN CLOB);
PROCEDURE print_clob_old (p_clob IN CLOB);
PROCEDURE print_clob_htp (p_clob IN CLOB);
PROCEDURE print_clob_htp_old (p_clob IN CLOB);
FUNCTION get_uri_paramter_value (p_uri IN VARCHAR2,
p_param_name IN VARCHAR2)
RETURN VARCHAR2;
END string_api;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY string_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/string_api.sql
-- Author : Tim Hall
-- Description : A package to hold string utilities.
-- Requirements :
-- Amendments :
-- When Who What
-- =========== ======== =================================================
-- 02-DEC-2004 Tim Hall Initial Creation
-- 31-AUG-2017 Tim Hall SUBSTR parameters switched.
-- 19-JAN-2017 Tim Hall Add get_uri_paramter_value function.
-- 20-NOV-2018 Tim Hall Reduce the chunk sizes to allow for multibyte character sets.
-- --------------------------------------------------------------------------
-- Variables to support the URI functionality.
TYPE t_uri_array IS TABLE OF VARCHAR2(32767) INDEX BY VARCHAR2(32767);
g_last_uri VARCHAR2(32767) := 'initialized';
g_uri_tab t_uri_array;
-- ----------------------------------------------------------------------------
FUNCTION split_text (p_text IN CLOB,
p_delimeter IN VARCHAR2 DEFAULT ',')
RETURN t_split_array IS
-- ----------------------------------------------------------------------------
-- Could be replaced by APEX_UTIL.STRING_TO_TABLE.
-- ----------------------------------------------------------------------------
l_array t_split_array := t_split_array();
l_text CLOB := p_text;
l_idx NUMBER;
BEGIN
l_array.delete;
IF l_text IS NULL THEN
RAISE_APPLICATION_ERROR(-20000, 'P_TEXT parameter cannot be NULL');
END IF;
WHILE l_text IS NOT NULL LOOP
l_idx := INSTR(l_text, p_delimeter);
l_array.extend;
IF l_idx > 0 THEN
l_array(l_array.last) := SUBSTR(l_text, 1, l_idx - 1);
l_text := SUBSTR(l_text, l_idx + 1);
ELSE
l_array(l_array.last) := l_text;
l_text := NULL;
END IF;
END LOOP;
RETURN l_array;
END split_text;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
PROCEDURE print_clob (p_clob IN CLOB) IS
-- ----------------------------------------------------------------------------
l_offset NUMBER := 1;
l_chunk NUMBER := 255;
BEGIN
LOOP
EXIT WHEN l_offset > LENGTH(p_clob);
DBMS_OUTPUT.put_line(SUBSTR(p_clob, l_offset, l_chunk));
l_offset := l_offset + l_chunk;
END LOOP;
END print_clob;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
PROCEDURE print_clob_old (p_clob IN CLOB) IS
-- ----------------------------------------------------------------------------
l_offset NUMBER := 1;
l_chunk NUMBER := 255;
BEGIN
LOOP
EXIT WHEN l_offset > DBMS_LOB.getlength(p_clob);
DBMS_OUTPUT.put_line(DBMS_LOB.substr(p_clob, l_offset, l_chunk));
l_offset := l_offset + l_chunk;
END LOOP;
END print_clob_old;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
PROCEDURE print_clob_htp (p_clob IN CLOB) IS
-- ----------------------------------------------------------------------------
l_offset NUMBER := 1;
l_chunk NUMBER := 3000;
BEGIN
LOOP
EXIT WHEN l_offset > LENGTH(p_clob);
HTP.prn(SUBSTR(p_clob, l_offset, l_chunk));
l_offset := l_offset + l_chunk;
END LOOP;
END print_clob_htp;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
PROCEDURE print_clob_htp_old (p_clob IN CLOB) IS
-- ----------------------------------------------------------------------------
l_offset NUMBER := 1;
l_chunk NUMBER := 3000;
BEGIN
LOOP
EXIT WHEN l_offset > DBMS_LOB.getlength(p_clob);
HTP.prn(DBMS_LOB.substr(p_clob, l_offset, l_chunk));
l_offset := l_offset + l_chunk;
END LOOP;
END print_clob_htp_old;
-- ----------------------------------------------------------------------------
-- ----------------------------------------------------------------------------
FUNCTION get_uri_paramter_value (p_uri IN VARCHAR2,
p_param_name IN VARCHAR2)
RETURN VARCHAR2 IS
-- ----------------------------------------------------------------------------
-- Example:
-- l_uri := 'https://localhost:8080/my_page.php?param1=value1&param2=value2&param3=value3';
-- l_value := string_api.get_uri_paramter_value(l_uri, 'param1')
-- ----------------------------------------------------------------------------
l_uri VARCHAR2(32767);
l_array t_split_array := t_split_array();
l_idx NUMBER;
BEGIN
IF p_uri IS NULL OR p_param_name IS NULL THEN
RAISE_APPLICATION_ERROR(-20000, 'p_uri and p_param_name must be specified.');
END IF;
IF p_uri != g_last_uri THEN
-- First time we've seen this URI, so build the key-value table.
g_uri_tab.DELETE;
g_last_uri := p_uri;
l_uri := TRANSLATE(g_last_uri, '&?', '^^');
l_array := split_text(l_uri, '^');
FOR i IN 1 .. l_array.COUNT LOOP
l_idx := INSTR(l_array(i), '=');
IF l_idx != 0 THEN
g_uri_tab(SUBSTR(l_array(i), 1, l_idx - 1)) := SUBSTR(l_array(i), l_idx + 1);
--DBMS_OUTPUT.put_line('param_name=' || SUBSTR(l_array(i), 1, l_idx - 1) ||
-- ' | param_value=' || SUBSTR(l_array(i), l_idx + 1));
END IF;
END LOOP;
END IF;
RETURN g_uri_tab(p_param_name);
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NULL;
END get_uri_paramter_value;
-- ----------------------------------------------------------------------------
END string_api;
/
SHOW ERRORS

View File

@@ -0,0 +1,76 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/switch_schema.sql
-- Author : Tim Hall
-- Description : Allows developers to switch synonyms between schemas where a single instance
-- : contains multiple discrete schemas.
-- Requirements : Must be loaded into privileged user such as SYS.
-- Usage : Create the package in a user that has the appropriate privileges to perform the actions (SYS)
-- : Amend the list of schemas in the "reset_grants" FOR LOOP as necessary.
-- : Call SWITCH_SCHEMA.RESET_GRANTS once to grant privileges to the developer role.
-- : Assign the developer role to all developers.
-- : Tell developers to use EXEC SWITCH_SCHEMA.RESET_SCHEMA_SYNONYMS ('SCHEMA-NAME'); to switch
-- : there synonyms between schemas.
-- Call Syntax : EXEC SWITCH_SCHEMA.RESET_SCHEMA_SYNONYMS ('SCHEMA-NAME');
-- Last Modified: 02/06/2003
-- -----------------------------------------------------------------------------------
CREATE OR REPLACE PACKAGE switch_schema AS
PROCEDURE reset_grants;
PROCEDURE reset_schema_synonyms (p_schema IN VARCHAR2);
END;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY switch_schema AS
PROCEDURE reset_grants IS
BEGIN
FOR cur_obj IN (SELECT owner, object_name, object_type
FROM all_objects
WHERE owner IN ('SCHEMA1','SCHEMA2','SCHEMA3','SCHEMA4')
AND object_type IN ('TABLE','VIEW','SEQUENCE', 'PACKAGE', 'PROCEDURE', 'FUNCTION', 'TYPE'))
LOOP
CASE
WHEN cur_obj.object_type IN ('TABLE','VIEW') THEN
EXECUTE IMMEDIATE 'GRANT SELECT, INSERT, UPDATE, DELETE ON ' || cur_obj.owner || '."' || cur_obj.object_name || '" TO developer';
WHEN cur_obj.object_type IN ('SEQUENCE') THEN
EXECUTE IMMEDIATE 'GRANT SELECT ON ' || cur_obj.owner || '."' || cur_obj.object_name || '" TO developer';
WHEN cur_obj.object_type IN ('PACKAGE', 'PROCEDURE', 'FUNCTION', 'TYPE') THEN
EXECUTE IMMEDIATE 'GRANT EXECUTE ON ' || cur_obj.owner || '."' || cur_obj.object_name || '" TO developer';
END CASE;
END LOOP;
END;
PROCEDURE reset_schema_synonyms (p_schema IN VARCHAR2) IS
v_user VARCHAR2(30) := USER;
BEGIN
-- Drop all existing synonyms
FOR cur_obj IN (SELECT synonym_name
FROM all_synonyms
WHERE owner = v_user)
LOOP
EXECUTE IMMEDIATE 'DROP SYNONYM ' || v_user || '."' || cur_obj.synonym_name || '"';
END LOOP;
-- Create new synonyms
FOR cur_obj IN (SELECT object_name, object_type
FROM all_objects
WHERE owner = p_schema
AND object_type IN ('TABLE','VIEW','SEQUENCE'))
LOOP
EXECUTE IMMEDIATE 'CREATE SYNONYM ' || v_user || '."' || cur_obj.object_name || '" FOR ' || p_schema || '."' || cur_obj.object_name || '"';
END LOOP;
END;
END;
/
SHOW ERRORS
CREATE PUBLIC SYNONYM switch_schema FOR switch_schema;
GRANT EXECUTE ON switch_schema TO PUBLIC;
CREATE ROLE developer;

View File

@@ -0,0 +1,18 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/table_comments.sql
-- Author : Tim Hall
-- Description : Displays comments associate with specific tables.
-- Requirements : Access to the DBA views.
-- Call Syntax : @table_comments (schema or all) (table-name or partial match)
-- Last Modified: 15/07/2000
-- -----------------------------------------------------------------------------------
SET VERIFY OFF
COLUMN table_name FORMAT A30
COLUMN comments FORMAT A40
SELECT table_name,
comments
FROM dba_tab_comments
WHERE owner = DECODE(UPPER('&1'), 'ALL', owner, UPPER('&1'))
AND table_name LIKE UPPER('%&2%')
ORDER BY table_name;

View File

@@ -0,0 +1,34 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/table_defs.sql
-- Author : Tim Hall
-- Description : Lists the column definitions for the specified table.
-- Call Syntax : @table_defs (tablee-name or all)
-- Last Modified: 24/09/2003
-- -----------------------------------------------------------------------------------
COLUMN column_id FORMAT 99
COLUMN data_type FORMAT A10
COLUMN nullable FORMAT A8
COLUMN size FORMAT A6
BREAK ON table_name SKIP 2
SET PAGESIZE 0
SET LINESIZE 200
SET TRIMOUT ON
SET TRIMSPOOL ON
SET VERIFY OFF
SELECT table_name,
column_id,
column_name,
data_type,
(CASE
WHEN data_type IN ('VARCHAR2','CHAR') THEN TO_CHAR(data_length)
WHEN data_scale IS NULL OR data_scale = 0 THEN TO_CHAR(data_precision)
ELSE TO_CHAR(data_precision) || ',' || TO_CHAR(data_scale)
END) "SIZE",
DECODE(nullable, 'Y', '', 'NOT NULL') nullable
FROM user_tab_columns
WHERE table_name = DECODE(UPPER('&1'), 'ALL', table_name, UPPER('&1'))
ORDER BY table_name, column_id;
SET PAGESIZE 14
SET LINESIZE 80

View File

@@ -0,0 +1,132 @@
-- -----------------------------------------------------------------------------------
-- File Name : https://oracle-base.com/dba/miscellaneous/table_differences.sql
-- Author : Tim Hall
-- Description : Checks column differences between a specified table or ALL tables.
-- : The comparison is done both ways so datatype/size mismatches will
-- : be listed twice per column.
-- : Log into the first schema-owner. Make sure a DB Link is set up to
-- : the second schema owner. Use this DB Link in the definition of
-- : the c_table2 cursor and amend v_owner1 and v_owner2 accordingly
-- : to make output messages sensible.
-- : The result is spooled to the Tab_Diffs.txt file in the working directory.
-- Call Syntax : @table_differences (table-name or all)
-- Last Modified: 15/07/2000
-- -----------------------------------------------------------------------------------
SET SERVEROUTPUT ON
SET LINESIZE 500
SET VERIFY OFF
SET FEEDBACK OFF
PROMPT
SPOOL Tab_Diffs.txt
DECLARE
CURSOR c_tables IS
SELECT a.table_name
FROM user_tables a
WHERE a.table_name = Decode(Upper('&&1'),'ALL',a.table_name,Upper('&&1'));
CURSOR c_table1 (p_table_name IN VARCHAR2,
p_column_name IN VARCHAR2) IS
SELECT a.column_name,
a.data_type,
a.data_length,
a.data_precision,
a.data_scale,
a.nullable
FROM user_tab_columns a
WHERE a.table_name = p_table_name
AND a.column_name = NVL(p_column_name,a.column_name);
CURSOR c_table2 (p_table_name IN VARCHAR2,
p_column_name IN VARCHAR2) IS
SELECT a.column_name,
a.data_type,
a.data_length,
a.data_precision,
a.data_scale,
a.nullable
FROM user_tab_columns@pdds a
WHERE a.table_name = p_table_name
AND a.column_name = NVL(p_column_name,a.column_name);
v_owner1 VARCHAR2(10) := 'DDDS2';
v_owner2 VARCHAR2(10) := 'PDDS';
v_data c_table1%ROWTYPE;
v_work BOOLEAN := FALSE;
BEGIN
Dbms_Output.Disable;
Dbms_Output.Enable(1000000);
FOR cur_tab IN c_tables LOOP
v_work := FALSE;
FOR cur_rec IN c_table1 (cur_tab.table_name, NULL) LOOP
v_work := TRUE;
OPEN c_table2 (cur_tab.table_name, cur_rec.column_name);
FETCH c_table2
INTO v_data;
IF c_table2%NOTFOUND THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : Present in ' || v_owner1 || ' but not in ' || v_owner2);
ELSE
IF cur_rec.data_type != v_data.data_type THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : DATA_TYPE differs between ' || v_owner1 || ' and ' || v_owner2);
END IF;
IF cur_rec.data_length != v_data.data_length THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : DATA_LENGTH differs between ' || v_owner1 || ' and ' || v_owner2);
END IF;
IF cur_rec.data_precision != v_data.data_precision THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : DATA_PRECISION differs between ' || v_owner1 || ' and ' || v_owner2);
END IF;
IF cur_rec.data_scale != v_data.data_scale THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : DATA_SCALE differs between ' || v_owner1 || ' and ' || v_owner2);
END IF;
IF cur_rec.nullable != v_data.nullable THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : NULLABLE differs between ' || v_owner1 || ' and ' || v_owner2);
END IF;
END IF;
CLOSE c_table2;
END LOOP;
FOR cur_rec IN c_table2 (cur_tab.table_name, NULL) LOOP
v_work := TRUE;
OPEN c_table1 (cur_tab.table_name, cur_rec.column_name);
FETCH c_table1
INTO v_data;
IF c_table1%NOTFOUND THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : Present in ' || v_owner2 || ' but not in ' || v_owner1);
ELSE
IF cur_rec.data_type != v_data.data_type THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : DATA_TYPE differs between ' || v_owner2 || ' and ' || v_owner1);
END IF;
IF cur_rec.data_length != v_data.data_length THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : DATA_LENGTH differs between ' || v_owner2 || ' and ' || v_owner1);
END IF;
IF cur_rec.data_precision != v_data.data_precision THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : DATA_PRECISION differs between ' || v_owner2 || ' and ' || v_owner1);
END IF;
IF cur_rec.data_scale != v_data.data_scale THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : DATA_SCALE differs between ' || v_owner2 || ' and ' || v_owner1);
END IF;
IF cur_rec.nullable != v_data.nullable THEN
Dbms_Output.Put_Line(cur_tab.table_name || '.' || cur_rec.column_name || ' : NULLABLE differs between ' || v_owner2 || ' and ' || v_owner1);
END IF;
END IF;
CLOSE c_table1;
END LOOP;
IF v_work = FALSE THEN
Dbms_Output.Put_Line(cur_tab.table_name || ' does not exist!');
END IF;
END LOOP;
END;
/
SPOOL OFF
PROMPT
SET FEEDBACK ON

View File

@@ -0,0 +1,111 @@
CREATE OR REPLACE PACKAGE BODY trc AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/trc.pkb
-- Author : Tim Hall
-- Description : A simple mechanism for tracing information to a table.
-- Requirements : trc.pks, dsp.pks, dsp.pkb and schema definied in trc.pks
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 08-JAN-2002 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
-- Package Variables
g_trace_on BOOLEAN := FALSE;
g_date_format VARCHAR2(50) := 'DD-MON-YYYY HH24:MI:SS';
-- Exposed Methods
-- --------------------------------------------------------------------------
PROCEDURE reset_defaults IS
-- --------------------------------------------------------------------------
BEGIN
g_trace_on := FALSE;
g_date_format := 'DD-MON-YYYY HH24:MI:SS';
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE trace_on IS
-- --------------------------------------------------------------------------
BEGIN
g_trace_on := TRUE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE trace_off IS
-- --------------------------------------------------------------------------
BEGIN
g_trace_on := FALSE;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE set_date_format (p_date_format IN VARCHAR2 DEFAULT 'DD-MON-YYYY HH24:MI:SS') IS
-- --------------------------------------------------------------------------
BEGIN
g_date_format := p_date_format;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN VARCHAR2,
p_trc_level IN NUMBER DEFAULT 5,
p_trc_user IN VARCHAR2 DEFAULT USER) IS
-- --------------------------------------------------------------------------
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF g_trace_on THEN
INSERT INTO trace_data
(id,
prefix,
data,
trc_level,
created_date,
created_by)
VALUES
(trc_seq.nextval,
p_prefix,
p_data,
p_trc_level,
Sysdate,
p_trc_user);
COMMIT;
END IF;
END;
-- --------------------------------------------------------------------------
-- --------------------------------------------------------------------------
PROCEDURE display (p_trc_level IN NUMBER DEFAULT NULL,
p_trc_user IN VARCHAR2 DEFAULT NULL,
p_from_date IN DATE DEFAULT NULL,
p_to_date IN DATE DEFAULT NUll) IS
-- --------------------------------------------------------------------------
CURSOR c_trace IS
SELECT *
FROM trace_data
WHERE trc_level = NVL(p_trc_level, trc_level)
AND created_by = NVL(p_trc_user, created_by)
AND created_date >= NVL(p_from_date, created_date)
AND created_date <= NVL(p_to_date, created_date)
ORDER BY id;
BEGIN
FOR cur_rec IN c_trace LOOP
dsp.line(cur_rec.prefix, cur_rec.data);
END LOOP;
END;
-- --------------------------------------------------------------------------
END trc;
/
SHOW ERRORS

View File

@@ -0,0 +1,46 @@
CREATE OR REPLACE PACKAGE trc AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/trc.pks
-- Author : Tim Hall
-- Description : A simple mechanism for tracing information to a table.
-- Requirements : trc.pkb, dsp.pks, dsp.pkb and:
--
-- CREATE TABLE trace_data (
-- id NUMBER(10) NOT NULL,
-- prefix VARCHAR2(50),
-- data VARCHAR2(2000) NOT NULL,
-- trc_level NUMBER(2) NOT NULL,
-- created_date DATE NOT NULL,
-- created_by VARCHAR2(50) NOT NULL);
--
-- ALTER TABLE trace_data ADD (CONSTRAINT trc_pk PRIMARY KEY (id));
--
-- CREATE SEQUENCE trc_seq;
--
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 08-JAN-2002 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
PROCEDURE reset_defaults;
PROCEDURE trace_on;
PROCEDURE trace_off;
PROCEDURE set_date_format (p_date_format IN VARCHAR2 DEFAULT 'DD-MON-YYYY HH24:MI:SS');
PROCEDURE line (p_prefix IN VARCHAR2,
p_data IN VARCHAR2,
p_trc_level IN NUMBER DEFAULT 5,
p_trc_user IN VARCHAR2 DEFAULT USER);
PROCEDURE display (p_trc_level IN NUMBER DEFAULT NULL,
p_trc_user IN VARCHAR2 DEFAULT NULL,
p_from_date IN DATE DEFAULT NULL,
p_to_date IN DATE DEFAULT NUll);
END trc;
/
SHOW ERRORS

View File

@@ -0,0 +1,246 @@
CREATE OR REPLACE PACKAGE ts_move_api AUTHID CURRENT_USER AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/ts_move_api.sql
-- Author : Tim Hall
-- Description : Allows you to move objects between tablespaces.
-- Requirements : The package should be run by a DBA user.
--
-- The following grants are needed for this package to compile.
--
-- GRANT SELECT ON dba_tables TO username;
-- GRANT SELECT ON dba_tab_partitions TO username;
-- GRANT SELECT ON dba_indexes TO username;
-- GRANT SELECT ON dba_ind_partitions TO username;
-- GRANT SELECT ON dba_lobs TO username;
--
-- License : Free for personal and commercial use.
-- You can amend the code, but leave existing the headers, current
-- amendments history and links intact.
-- Copyright and disclaimer available here:
-- https://oracle-base.com/misc/site-info.php#copyright
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 20-JUN-2010 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
PROCEDURE move_tables(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
);
PROCEDURE move_part_tables(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
);
PROCEDURE move_indexes(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
);
PROCEDURE move_part_indexes(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
);
PROCEDURE move_lobs(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
);
END ts_move_api;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY ts_move_api AS
-- --------------------------------------------------------------------------
-- Name : https://oracle-base.com/dba/miscellaneous/ts_move_api.sql
-- Author : Tim Hall
-- Description : Allows you to move objects between tablespaces.
-- Requirements : The package should be run by a DBA user.
--
-- The following grants are needed for this package to compile.
--
-- GRANT SELECT ON dba_tables TO username;
-- GRANT SELECT ON dba_tab_partitions TO username;
-- GRANT SELECT ON dba_indexes TO username;
-- GRANT SELECT ON dba_ind_partitions TO username;
-- GRANT SELECT ON dba_lobs TO username;
--
-- License : Free for personal and commercial use.
-- You can amend the code, but leave existing the headers, current
-- amendments history and links intact.
-- Copyright and disclaimer available here:
-- https://oracle-base.com/misc/site-info.php#copyright
-- Ammedments :
-- When Who What
-- =========== ======== =================================================
-- 20-JUN-2010 Tim Hall Initial Creation
-- --------------------------------------------------------------------------
g_sql VARCHAR2(32767);
-- -----------------------------------------------------------------------------
PROCEDURE move_tables(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
) AS
BEGIN
FOR cur_rec IN (SELECT owner, table_name
FROM dba_tables
WHERE tablespace_name = UPPER(p_from_ts)
AND partitioned = 'NO'
AND temporary = 'N')
LOOP
BEGIN
g_sql := 'ALTER TABLE "' || cur_rec.owner || '"."' || cur_rec.table_name || '" MOVE TABLESPACE ' || p_to_ts;
EXECUTE IMMEDIATE g_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR: ' || g_sql);
DBMS_OUTPUT.put_line('ERROR: ' || SQLERRM);
END;
END LOOP;
END move_tables;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
PROCEDURE move_part_tables(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
) AS
BEGIN
-- Table partitions.
FOR cur_rec IN (SELECT table_owner, table_name, partition_name
FROM dba_tab_partitions
WHERE tablespace_name = UPPER(p_from_ts))
LOOP
BEGIN
g_sql := 'ALTER TABLE "' || cur_rec.table_owner || '"."' || cur_rec.table_name || '" MOVE PARTITION "' || cur_rec.partition_name || '" TABLESPACE ' || p_to_ts;
EXECUTE IMMEDIATE g_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR: ' || g_sql);
DBMS_OUTPUT.put_line('ERROR: ' || SQLERRM);
END;
END LOOP;
-- Partitioned table defaults.
FOR cur_rec IN (SELECT owner, table_name
FROM dba_tables
WHERE tablespace_name = UPPER(p_from_ts)
AND partitioned = 'YES')
LOOP
BEGIN
g_sql := 'ALTER TABLE "' || cur_rec.owner || '"."' || cur_rec.table_name || '" MODIFY DEFAULT ATTRIBUTES TABLESPACE ' || p_to_ts;
EXECUTE IMMEDIATE g_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR: ' || g_sql);
DBMS_OUTPUT.put_line('ERROR: ' || SQLERRM);
END;
END LOOP;
END move_part_tables;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
PROCEDURE move_indexes(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
) AS
BEGIN
FOR cur_rec IN (SELECT owner, index_name
FROM dba_indexes
WHERE tablespace_name = UPPER(p_from_ts)
AND partitioned = 'NO'
AND index_type != 'LOB')
LOOP
BEGIN
g_sql := 'ALTER INDEX "' || cur_rec.owner || '"."' || cur_rec.index_name || '" REBUILD TABLESPACE ' || p_to_ts;
EXECUTE IMMEDIATE g_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR: ' || g_sql);
DBMS_OUTPUT.put_line('ERROR: ' || SQLERRM);
END;
END LOOP;
END move_indexes;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
PROCEDURE move_part_indexes(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
) AS
BEGIN
-- Index partitions.
FOR cur_rec IN (SELECT index_owner, index_name, partition_name
FROM dba_ind_partitions
WHERE tablespace_name = UPPER(p_from_ts))
LOOP
BEGIN
g_sql := 'ALTER INDEX "' || cur_rec.index_owner || '"."' || cur_rec.index_name || '" REBUILD PARTITION "' || cur_rec.partition_name || '" TABLESPACE ' || p_to_ts;
EXECUTE IMMEDIATE g_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR: ' || g_sql);
DBMS_OUTPUT.put_line('ERROR: ' || SQLERRM);
END;
END LOOP;
-- Partitioned index default.
FOR cur_rec IN (SELECT owner, index_name
FROM dba_indexes
WHERE tablespace_name = UPPER(p_from_ts)
AND partitioned = 'YES')
LOOP
BEGIN
g_sql := 'ALTER INDEX "' || cur_rec.owner || '"."' || cur_rec.index_name || '" MODIFY DEFAULT ATTRIBUTES TABLESPACE ' || p_to_ts;
EXECUTE IMMEDIATE g_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR: ' || g_sql);
DBMS_OUTPUT.put_line('ERROR: ' || SQLERRM);
END;
END LOOP;
END move_part_indexes;
-- -----------------------------------------------------------------------------
-- -----------------------------------------------------------------------------
PROCEDURE move_lobs(
p_from_ts IN VARCHAR2,
p_to_ts IN VARCHAR2
) AS
BEGIN
FOR cur_rec IN (SELECT owner, table_name, column_name
FROM dba_lobs
WHERE tablespace_name = UPPER(p_from_ts)
AND partitioned = 'NO')
LOOP
BEGIN
g_sql := 'ALTER TABLE "' || cur_rec.owner || '"."' || cur_rec.table_name || '" MOVE LOB("' || cur_rec.column_name || '") STORE AS (TABLESPACE ' || p_to_ts || ')';
EXECUTE IMMEDIATE g_sql;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR: ' || g_sql);
DBMS_OUTPUT.put_line('ERROR: ' || SQLERRM);
END;
END LOOP;
END move_lobs;
-- -----------------------------------------------------------------------------
END ts_move_api;
/
SHOW ERRORS