Home » SQL & PL/SQL » SQL & PL/SQL » Extract CREATE TABLE statements from USER_TAB_COLUMNS (11g, linux)
Extract CREATE TABLE statements from USER_TAB_COLUMNS [message #381417] |
Fri, 16 January 2009 17:17 |
tmcallister
Messages: 107 Registered: December 2007
|
Senior Member |
|
|
I'm trying to extract some create table statements from my database, however I'm running into the 4000 varchar2 limit within SYS_CONNECT_BY_PATH, and as far as I can tell there is absolutely nothing that I can do about it.
Here is the query that I have so far:
SELECT 'create table '
|| UPPER (table_name)
|| CHR (10)
|| '('
|| CHR (10)
|| SUBSTR (SYS_CONNECT_BY_PATH ( column_name
|| CHR (9)
|| data_type
|| DECODE (data_type,
'DATE', '',
'NUMBER', '('
|| data_precision
|| ','
|| data_scale
|| ')',
'('
|| data_length
|| ')'
|| DECODE (nullable,
'N', CHR (9)
|| 'NOT NULL'
)
|| DECODE (column_id,
cnt, '',
','
)
),
'
'
),
0
)
|| CHR (10)
|| ');'
FROM (SELECT table_name, column_name, data_type, data_length,
data_precision, data_scale, column_id, nullable,
COUNT (*) OVER (PARTITION BY table_name) cnt
FROM user_tab_columns)
WHERE column_id = cnt
START WITH column_id = 1
CONNECT BY PRIOR column_id + 1 = column_id AND PRIOR table_name = table_name;
It works, except when you get an exceptionally large table (which I happen to have a few of) where the result of the SYS_CONNECT_BY_PATH clause is >4000 characters.
Another relatively minor issue is that I cannot find anyway to get the connecting character to be a carriage return except by using: '
'
Which I *REALLY* don't like, but I cannot get it to take a CHR() code however I try to format it.
Any tips/thoughts?
I suppose my only real option is to drop into pl/sql and use a cursor ... I really prefer to keeps things straight sql whenever possible .
[Updated on: Fri, 16 January 2009 17:24] Report message to a moderator
|
|
|
|
Re: Extract CREATE TABLE statements from USER_TAB_COLUMNS [message #381420 is a reply to message #381418] |
Fri, 16 January 2009 18:20 |
tmcallister
Messages: 107 Registered: December 2007
|
Senior Member |
|
|
Yes apparently I am, and no there is no reason for me to.
Quick question though, is there a way to simplify/dumb down the result?
I.e. given:
CREATE TABLE deleteme
( col1 VARCHAR2(32) );
commit;
select dbms_metadata.GET_DDL('TABLE','DELETEME','<REMOVED>') from dual;
I would like to see:
CREATE TABLE deleteme
( col1 VARCHAR2(32) );
Rather than:
CREATE TABLE "<removed>"."DELETEME"
( "COL1" VARCHAR2(32)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "<removed>"
White spaces/formatting does not matter, however I'd like to get rid of everything after and including PCTFREE...
[Updated on: Fri, 16 January 2009 18:21] Report message to a moderator
|
|
|
Re: Extract CREATE TABLE statements from USER_TAB_COLUMNS [message #381422 is a reply to message #381417] |
Fri, 16 January 2009 18:46 |
tmcallister
Messages: 107 Registered: December 2007
|
Senior Member |
|
|
And to 'almost' answer my own question:
CREATE TABLE deleteme
( col1 VARCHAR2(32) );
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',false);
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',true);
select dbms_metadata.GET_DDL('TABLE','DELETEME') || ';' from dual;
Gets me to
CREATE TABLE "<SCHEMA>"."DELETEME"
( "COL1" VARCHAR2(32)
) ;
How do I get rid of "<SCHEMA>"?
Can't find anything here: http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_metada.htm#BGBJBFGE
I suppose REPLACE could work but that seems dangerous...
SELECT REPLACE (DBMS_METADATA.get_ddl ('TABLE', 'DELETEME'), '"<SCHEMA>".', '')
FROM DUAL;
[Updated on: Fri, 16 January 2009 18:47] Report message to a moderator
|
|
|
|
Re: Extract CREATE TABLE statements from USER_TAB_COLUMNS [message #381756 is a reply to message #381444] |
Mon, 19 January 2009 12:07 |
tmcallister
Messages: 107 Registered: December 2007
|
Senior Member |
|
|
Yeah I'd be more comfortable using the longer string, that should be fine.
So this is what I'm using:
prompt SET ECHO OFF NEWP 0 SPA 0 PAGES 0 FEED OFF HEAD OFF TRIMS ON LINESIZE 8192 ARRAYSIZE 5000 TERMOUT OFF VERIFY OFF
prompt EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',false);
prompt EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',true);
prompt EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'CONSTRAINTS',false);
prompt EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'REF_CONSTRAINTS',false);
prompt spool create_tables.sql
SELECT 'SELECT REPLACE (DBMS_METADATA.get_ddl (''TABLE'', '''
|| table_name
|| '''), ''CREATE TABLE "EXPR".'', ''CREATE TABLE '') from dual;'
FROM user_tables
ORDER BY table_name;
prompt spool off
spool off
@ddl_table_extract
However the output isn't what I'd expect... Every single table is cut off on the second line...
Result from the sql spool script:
CREATE TABLE "APC_AREA_OFFICE"
( "CODE" VARCHAR2(12),
"VALUE" VARCHAR2(
CREATE TABLE "APC_ENVIRONMENT"
( "CODE" VARCHAR2(12),
"VALUE" VARCHAR2(
Result from manual
CREATE TABLE "APC_AREA_OFFICE"
( "CODE" VARCHAR2(12),
"VALUE" VARCHAR2(50)
) ;
CREATE TABLE "APC_ENVIRONMENT"
( "CODE" VARCHAR2(12),
"VALUE" VARCHAR2(50)
) ;
Any idea what is up? Does spool not interact well with clobs or ...?
|
|
|
|
|
|
|
|
Re: Extract CREATE TABLE statements from USER_TAB_COLUMNS [message #381768 is a reply to message #381762] |
Mon, 19 January 2009 13:01 |
tmcallister
Messages: 107 Registered: December 2007
|
Senior Member |
|
|
Did my research in advance on this one, and it's stumping me so far.
There seems to be some interaction between spool and clobs that is causing it to ignore linesize and print out the data in 80 character chunks.
SET ECHO OFF NEWP 0 SPA 0 PAGES 0 FEED OFF HEAD OFF TRIMS ON LINESIZE 8192 LONG 8192 ARRAYSIZE 5000 TERMOUT OFF VERIFY OFF
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SEGMENT_ATTRIBUTES',false);
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',true);
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'CONSTRAINTS',false);
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'REF_CONSTRAINTS',false);
-- create indexes DDL
set linesize 8192 -- set it again just in case
spool create_indexes.sql
SELECT REPLACE (REPLACE (DBMS_METADATA.get_ddl ('INDEX', index_name),
'INDEX "<SCHEMA>".',
'INDEX '
),
'ON "<SCHEMA>".',
'ON '
)
FROM user_indexes
ORDER BY table_name;
spool off
Any thoughts?
[Updated on: Mon, 19 January 2009 13:04] Report message to a moderator
|
|
|
|
|
|
|
Goto Forum:
Current Time: Tue Dec 03 12:02:34 CST 2024
|