Code generation scripts in PL/SQL
Flattening XML paths
The table elephant_castle
has a XMLTYPE
column details
that we want to
get a list of distinct node paths.
WITH node_list AS ( SELECT x.* FROM elephant_castle ec CROSS JOIN XMLTABLE ( 'declare function local:path-to-node( $nodes as node()* ) as xs:string* { $nodes/string-join(ancestor-or-self::*/name(.),''/'') } ;for $i in $doc//* let $node_path := local:path-to-node($i) (: still don''t have a clue how this func works :) let $node_value := $i/text() where string-length($node_value) > 0 (: how to exclude nodes without values :) return <data> <path>{$node_path}</path> <value>{$node_value}</value> </data>' PASSING ec.details AS "doc" COLUMNS node_path VARCHAR2(4000) PATH 'path', node_value VARCHAR2(4000) PATH 'value' /* debugging */ ) x ) SELECT distinct nl.node_path FROM node_list nl;
Generate a query that combines existing fields with newly flatten XML paths
This script allows you to apply boiler plate (fields from the existing table
using the data dictionary) and then make call out to another sqlplus script
that contains table specific mappings. The call out script is assumed to be
called TableName.sql
.
REM Suppress all headings, page breaks, titles
SET PAGESIZE 0
REM Do not list the text of a command before and after replacing substitution
REM variables with values
SET VERIFY OFF
REM Do not display the number of records returned (when rows >= n )
SET FEEDBACK OFF
CLEAR SCREEN
DEFINE TableName=STANDINGORDER
DEFINE TableAlias=so
DEFINE TableSchema=BPHADMIN
/*******************************************************************************
** Generate existing column list, excluding XMLTYPE, BLOB and CLOB types.
*******************************************************************************/
WITH column_list AS (
SELECT
column_id,
column_name
FROM
all_tab_cols
WHERE
owner = '&TableSchema'
AND
table_name = '&TableName'
AND
data_type NOT IN (
'XMLTYPE','BLOB','CLOB'
)
ORDER BY column_id
) SELECT
CASE column_id
WHEN 1 THEN 'SELECT &TableAlias'|| '.' || column_name
ELSE ',&TableAlias'|| '.' || column_name
END as sql
FROM
column_list;
/*******************************************************************************
** Call out script with custom XML flattening logic (usually field name tweaks)
*******************************************************************************/
@&TableName
/*******************************************************************************
** Add "FROM" statement
*******************************************************************************/
PROMPT FROM &TableName &TableAlias;;