Prevent output of SPOOL from being wrapped - oracle

I'm trying to generate all DDLs for objects in a Database using the SPOOL command in SQLPLUS:
SET trimspool ON
SET wrap off
SET heading off
SET linesize 300
SET echo off
SET pages 999
SET long 90000
Col object_type format a10000
Col object_name format a10000
Col owner format a10000
spool export.out
SELECT DBMS_METADATA.GET_DDL(object_type, object_name, owner)
FROM all_OBJECTS
WHERE OWNER = 'DMALM'
and object_type not like '%PARTITION'
and object_type not like '%BODY'
and object_type not like '%LOB';
spool off
quit
But the output file I get is cut at col #80.
How can I prevent the output file from being wrapped?

You need to also do:
SET longchunksize 90000
As the documentation says:
The default width of datatype columns is the width of the column in the database. The column width of a LONG, BLOB, BFILE, CLOB, NCLOB or XMLType defaults to the value of SET LONGCHUNKSIZE or SET LONG, whichever is the smaller.
You're setting LONG already, but LONGCHUNKSIZE is still at its default value of 80, so you need to increase that to match. You can see all your current settings with show all.
This preserves the line breaks and indentation applied by default.

How about using word_wrapped?
SET trimspool ON
SET heading off
SET linesize 300
SET echo off
SET pages 999
SET long 90000
set termout off
column txt format a121 word_wrapped
Col object_type format a10000
Col object_name format a10000
Col owner format a10000
spool export.out
SELECT DBMS_METADATA.GET_DDL(object_type, object_name, owner)txt
FROM all_OBJECTS
WHERE OWNER = 'DMALM'
and object_type not like '%PARTITION'
and object_type not like '%BODY'
and object_type not like '%LOB';
spool off
quit

Sounds like you may want to try:
set longchunksize 100
or equivalent. Experiment with the number see if it helps.
Source Oracle Docs

The following works. You can download all SPs under one schema. You can also download one SP at a time.
CREATE or replace DIRECTORY DIR_DDL AS '/dir_name';
grant read, write on directory DIR_DDL to user_name;
-- ====================================================
-- NOTE: Need to use the object owner user, not SYS.
-- ====================================================
DECLARE
v_ddl_clob CLOB;
BEGIN
FOR c IN ( SELECT object_name, object_type
FROM dba_objects
WHERE object_type IN ('PROCEDURE')
AND OWNER = 'SYS'
AND object_name = 'SP_NAME' )
LOOP
-- You want "/" in a new line. Otherwise, it will not work
v_ddl_clob := dbms_metadata.get_ddl(c.object_type, c.object_name) ||'
/';
-- write to SQL directory :
dbms_xslprocessor.clob2file(v_ddl_clob, 'DIR_DDL', c.object_name||'.sql');
END LOOP;
END;
/

Related

Is there any PL/SQL script to modify column value of each table in each schema of Oracle Database

I have written pl/sql code to modify column values in a table of one schema. But I need to execute the same script in each table of each schema. I will take the list of the table name, column name from spreadsheet.
define schema_name = 'D';
define hours_offset = '(-3/24)';
set echo off;
set timi off;
set heading off;
set feedback off;
set linesize 250;
spool convert_01.sql
select 'set echo on;' from dual;
select 'set timi on;' from dual;
select 'set heading on;' from dual;
select 'set feedback on;' from dual;
select 'set linesize 250;' from dual;
select 'spool convert_01.log;' from dual;
select 'update '||owner||'.'||table_name||' set '||column_name||'
='||column_name||' + &hours_offset;'
from dba_tab_columns where owner = '&schema_name' and
(
data_type = 'DATE' or
data_type like 'TIMESTAMP%'
) and
data_type not like 'TIMESTAMP%WITH TIME ZONE'
order by owner, table_name, column_name;
select 'spool off;' from dual;
spool off;
I need to execute the same script in each table of each schema
That's most probably not true. There are users (schemas) you shouldn't modify at all, e.g. SYS, SYSTEM, CTXSYS, APEX180200 and such.
Therefore, you'd rather collect list of users you want to skip (or the ones you want to affect; it's up to you). That list would then be used instead of '&schema_name'.
A simple option is to store list of users into a table and use its contents as a subquery in your current script.
Unrelated, but:
I have written pl/sql code ...
Nope; what you wrote is a pure SQL script readable by SQL*Plus (and, possibly, some other tools which understand commands you used).

Where is the rest of Oracle's V$ view definitions?

The view V$FIXED_VIEW_DEFINITION contains the definition of all V$ views. However, the datatype is VARCHAR2(4000), so only the first 4000 characters of the view's body are displayed:
SELECT column_name, data_type, data_length
FROM dba_tab_cols
WHERE table_name = 'V_$FIXED_VIEW_DEFINITION';
COLUMN_NAME DATA_TYPE DATA_LENGTH
--------------- --------- -----------
VIEW_NAME VARCHAR2 128
VIEW_DEFINITION VARCHAR2 4000
CON_ID NUMBER 22
This works fine for views which are shorter, but for others, like V$SESSION, the query text stops right after character 4000:
SELECT * FROM v$fixed_view_definition WHERE view_name = 'GV$SESSION';
VIEW_NAME VIEW_DEFINITION
---------- --------------------------------------------
GV$SESSION select s.inst_id, ... ,decode(bitand(s.ksuse
here it stops abruptly ^
Now, obviously, Oracle has stored the full text somewhere, and the function DBMS_UTILITY. EXPAND_SQL_TEXT T reconstructs the full query, but not without doing strange things to the query like quoting all columns, introducing alias etc:
DECLARE
c CLOB;
i NUMBER := 1;
linelen CONSTANT NUMBER := 100;
BEGIN
DBMS_UTILITY.EXPAND_SQL_TEXT('SELECT * FROM V$SESSION', c);
LOOP
EXIT WHEN i > DBMS_LOB.GETLENGTH(c);
DBMS_OUTPUT.PUT_LINE(DBMS_LOB.SUBSTR(c, linelen, i));
i := i + linelen;
END LOOP;
END;
/
SELECT "A1"."SADDR" "SADDR","A1"."SID" "SID","A1"."SERIAL#" "SERIAL#","A1"."AUDS
ID" "AUDSID","A1"."PADDR" "PADDR","A1"."USER#" "USER#","A1"."USERNAME" "USERNAME
...
So, where is the rest of the V$ query bodies?
For the sake of having a clean answer, it sounds like you discovered the full fixed view source queries compiled into the Oracle binary by using
strings $ORACLE_HOME/bin/oracle
and grepping the output for a specific view.
Burleson had provided a hint that the fixed view synonyms are created by the $ORACLE_HOME/rdbms/admin/ catalog scripts (specifically cdfixed.sql).
try this,
spool C:\Users\test\Downloads\VW_DDL.txt
SET LONG 200000 LONGCHUNKSIZE 500000 PAGESIZE 0 LINESIZE 1000 FEEDBACK OFF VERIFY OFF TRIMSPOOL ON
SELECT DBMS_METADATA.get_ddl ('VIEW', view_name, 'SYSADM')
FROM all_views
WHERE owner = 'SYSADM'
AND view_name IN (' ');
SET PAGESIZE 14 LINESIZE 100 FEEDBACK ON VERIFY ON
spool off

Set a line size to a spooling in command windows

I'm using PL/SQL Developer version 11.0.6.1776
When I launch the script in my command window, the name of the file I'm spooling is incomplete.
This is the script I have:
set pagesize 0
set long 90000
SET TERMOUT OFF
spool out.sql
select 'spool C:\Users\personal\MAIN_USR\index\'||REPLACE(index_name, '$', '_')||'.txt'||chr(13)||chr(10)||
'SELECT DBMS_METADATA.GET_DDL(''INDEX'','''||index_name||''',''MTO_INDX'') '||chr(13)||chr(10)||
'FROM DUAL;'||chr(13)||chr(10)||
'spool off' as cmd
FROM user_indexes ui
INNER JOIN MTTO_TAB_EXIST_ALL tea USING(table_name)
WHERE tea.MRK_DEL_PERM = 'Y'
AND tea.OWNER_NM = 'MTO_INDX'
AND MCA_BACKUP_DDL != 'Y';
spool off
#OUT.SQL
exit
In the spooling, some files look like this below:
spool C:\Users\personal\MAIN_USR\index\CIA_PRD_PRDR_DISTR_INV_3242.t
The file extension should be .txt, but for some reason it is incomplete and other spooling files only have a part of the name
I appreciate any help to fix this
Well, in SQL*Plus, it is e.g.
set linesize 100
which sets its length. I don't know whether it works in PL/SQL Developer as well.
On the other hand, even if line size is set to a low number (e.g. 50), SQL*Plus will "break" the line and move the rest of the text into the next line:
SQL> set linesize 50
SQL>
SQL> select 'spool C:\Users\personal\MAIN_USR\index\'||REPLACE(index_name, '$', '_')||'.txt'||chr(13)||chr(10)||
2 'SELECT DBMS_METADATA.GET_DDL(''INDEX'','''||index_name||''',''MTO_INDX'') '||chr(13)||chr(10)||
3 'FROM DUAL;'||chr(13)||chr(10)||
4 'spool off' as cmd
5 from (select 'i01_abc_omm' index_name from dual);
CMD
--------------------------------------------------
spool C:\Users\personal\MAIN_USR\index\i01_abc_omm
.txt --> see? Moved to the next line
SELECT DBMS_METADATA.GET_DDL('INDEX','i01_abc_omm'
,'MTO_INDX')
FROM DUAL;
spool off
That's why I'm not sure it'll actually help, but - you can try.

How to do dynamic spool's using sqlplus by batch-file

I'm trying save multiples txt archives with querye result using a single .sql archive called by a batch-file for automate-work.
My Batch-file:
set d=%location%result.txt
set f=%location%result2.txt
echo exit | sqlplus GOVMANPATCHORACLE/GOVMANPATCHORACLE#%SERVER%/%SERVICE% #C:\Users\enrique.erbs\Desktop\JOB\Tools\extrator_parametros\queryoracle.sql '%d%' '%f%'
*'%d%' contains the save locale to spool
My archive .sql (queryoracle.sql):
SET PAGESIZE 50000
SET LINESIZE 800
SET VERIFY OFF
SET ECHO ON
SET HEAD ON
SET SERVEROUTPUT ON;
SET PAGES 0
SET DEFINE ON;
COLUMN COD_PARAMETRO FORMAT a100 HEADING COD_PARAMETRO;
COLUMN DES_PARAMETRO FORMAT a100 HEADING DES_PARAMETRO;
COLUMN DES_VALOR FORMAT a100 HEADING DES_VALOR;
DECLARE
myvar1 varchar2(30);
myvar2 varchar2(30);
BEGIN
myvar1 := '$1';
myvar2 := '$2';
SPOOL 'myvar1'
SELECT TDFE_PARAMETRO_APLICACAO.COD_PARAMETRO AS COD_PARAMETRO, TDFE_PARAMETRO.DES_PARAMETRO AS DES_PARAMETRO, TDFE_PARAMETRO_APLICACAO.DES_VALOR AS DES_VALOR FROM TDFE_PARAMETRO_APLICACAO INNER JOIN TDFE_PARAMETRO ON(TDFE_PARAMETRO_APLICACAO.COD_PARAMETRO=TDFE_PARAMETRO.COD_PARAMETRO);
SPOOL OFF
SPOOL 'myvar2'
SELECT * FROM TDFE_PARAMETRO_APLICACAO;
SPOOL OFF
END;
I tryed some options and the most closest to get the result what i want is using ">> %location%\result.txt" at end of sqlplus call.
Somebody can help me ?
You were not far at all. Actually, When executing SQLPLUS and passing him a file to execute and arguments, It will replace every single occurence of &1 By your first Argument, Every occurence of &2 by your second argument, etc ...
This should work :
SET PAGESIZE 50000
SET LINESIZE 800
SET VERIFY OFF
SET ECHO ON
SET HEAD ON
SET SERVEROUTPUT ON;
SET PAGES 0
SET DEFINE ON;
COLUMN COD_PARAMETRO FORMAT a100 HEADING COD_PARAMETRO;
COLUMN DES_PARAMETRO FORMAT a100 HEADING DES_PARAMETRO;
COLUMN DES_VALOR FORMAT a100 HEADING DES_VALOR;
SPOOL '&1'
SELECT TDFE_PARAMETRO_APLICACAO.COD_PARAMETRO AS COD_PARAMETRO, TDFE_PARAMETRO.DES_PARAMETRO AS DES_PARAMETRO, TDFE_PARAMETRO_APLICACAO.DES_VALOR AS DES_VALOR FROM TDFE_PARAMETRO_APLICACAO INNER JOIN TDFE_PARAMETRO ON(TDFE_PARAMETRO_APLICACAO.COD_PARAMETRO=TDFE_PARAMETRO.COD_PARAMETRO);
SPOOL OFF
SPOOL '&2'
SELECT * FROM TDFE_PARAMETRO_APLICACAO;
SPOOL OFF
For reference : https://docs.oracle.com/cd/E11882_01/server.112/e16604/ch_twelve044.htm#SQPUG127

how to output any given table in oracle to csv using sqlplus

I want a way of dynamically exporting any given table in oracle 11g to a csv using sql*plus - instead of needing to explicitly hard code the column names each time.
Please use following syntax.
SET MARKUP HTML ON SPOOL ON
HEAD "<title>Data Extract</title> - <meta http-equiv='Content-Type' content='application/vnd.ms-excel;'>
<style type='text/css'>
</style>"
SET ECHO OFF
SPOOL output.xls
select * from &tablename ;
spool off
exit
Enter tablename when prompted.
Abhi
You can use the SET Colsep option.
SET COLSEP ","
SET PAGES 0
SET FEEDBACK OFF
SPOOL output.csv
select * from HR.employees;
spool off
exit
After searching stack overflow I could not find an exact answer to this problem - therefore I developed my own solution.
Here is the sql script that I wrote:
SET echo off
SET verify off
SET heading off
SET pages 50000
SET feedback off
SET newpage none
SET termout off
SET linesize 900
SET trimspool on
SET serveroutput on
define table_name = &1
define spool_path = &2
var rc refcursor
column qry new_val capture
SELECT 'select ''"'' || ' || listagg(column_name,' || ''","'' || ') within group (order by column_id) || ' || ''"'' as rec from &table_name' qry
FROM user_tab_cols
WHERE table_name = '&table_name';
spool &spool_path
SELECT listagg(column_name,',') WITHIN GROUP (ORDER BY column_id)
FROM user_tab_cols
WHERE table_name = '&table_name';
BEGIN
FOR v_rec IN (&capture) LOOP
dbms_output.put_line(v_rec.rec);
END LOOP;
END;
/
spool off
EXIT
The script requires two parameters - the first parameter is the table name, and the second is the spool path.
Essentially the first query:
SELECT 'select ''"'' || ' || listagg(column_name,' || ''","'' || ') within group (order by column_id) || ' || ''"'' as rec from &table_name' qry
FROM user_tab_cols
WHERE table_name = '&table_name';
Dynamically creates a new select statement (which loads into the &capture substitution variable) using user_tab_cols and listagg to force each column name onto a single line - this dynamically created select statement will essentially concatenate each column together separated by commas. Later when we spool we loop through the dynamically generated select statement to produce each row of data.
The header is produced by a similar query (the first action once we begin spooling), however for this we can just listagg the column header names together directly.
It is easier to understand by testing the two queries on a table of your choice to see the result!

Resources