Set a line size to a spooling in command windows - oracle

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.

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).

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!

Oracle : Export select statement result set as INSERT SQL Statements similar to SQL developer export

I am looking for a solution to create the SQL INSERT statements using PL/SQL script for the select statement result set. Looking for similar feature available in the SQL Developer tool (export --> format insert) but I want the solution as script rather than using any tool(s).
I have referred the below solution. However, I would like to know whether any better way to do it as the solution is old and not very simple.
EXPORT AS INSERT STATEMENTS: But in SQL Plus the line overrides 2500 characters!
I just found a simple solution for my problem using oracle hint ("insert"). This automatically take care the data type as well. My table has only string and numeric data types, so it works fine for me. I have not tested the solution for other data types. However, I hope it would work for other data types as well.
set linesize 2000
set pagesize 10
spool "c:\myoutput.txt";
select /*insert*/ * from SAMPLE_TABLE;
spool off;
as a script you say...
Use SQLcl - it's a command-line interface for SQL Developer.
You can create a .bat or .sh script to launch SQLcl, run your query, spool it to a file, no need to write any code.
set pagesize...
set head...
set feedback...
spool...
set sqlformat insert
select * from sample_table;
spool off
exit
set sqlformat insert
In my case initially it didn't work in SQL developer as the version was version 3.2 and resulted with message in the script output:
oracle unknown set option sqlformat insert
As i upgraded to the SQL developer 4.2 and above and using "Run Script" (F5) i was able to export the select records as the insert scripts.
You can do it with an for loop and dbms output as you want, even as merge statements like Toad, just make the buffer big enough:
BEGIN
FOR r_cur IN ( SELECT column_one,
column_two,
column_three,
column_value
FROM some_table
WHERE column_one LIKE 'something%'
ORDER BY column_one, column_two, column_three)
LOOP
DBMS_OUTPUT.put_line (
'MERGE INTO some_table A USING
(SELECT\n
''' || r_cur.column_one || ''' as column_one,
''' || r_cur.column_two || ''' as column_two,
''' || r_cur.column_three || ''' as column_three,
''' || r_cur.column_value || ''' as column_value
FROM DUAL) B
ON (A.column_one = B.column_one and A.column_two = B.column_two and A.column_three = B.column_three)
WHEN NOT MATCHED THEN
INSERT (
column_one, column_two, column_three, column_value)
VALUES (
B.column_one, B.column_two, B.column_three, B.column_value)
WHEN MATCHED THEN
UPDATE SET
A.column_value = B.column_value;
' );
END LOOP;
END;
/
Not really PL/SQL, but basic SQL can handle a request as simple as this:
set linesize 2000
set pagesize 0
spool c:\myoutput.txt
select 'INSERT INTO SAMPLE_TABLE VALUES ('''||
C01||''','||C02||','||C03||','||C04||','''||C05||''','''||
C06||''','''||C07||''','||C08||','||C09||','''||C10||''','''||
C10||''','''||C11||''','''||C12||''','''||C13||''','''||C14||''','''||
C15||''','''||C16||''');'
from sample_table;
spool off
Note: This is using the table example from the URL you referenced in your post. In the example in the URL, C02, C03, C04, C08, and C09 are all NUMBER, the rest are CHAR or VARCHAR2

Select consecutive values with interval

I am stuck with this code:
REM AWR-Generator.sql: Script for creating multiple consecutive Oracle AWR Reports
REM
REM Creates an output SQL script which, when run, will generate all AWR Reports
REM between the specificed start and end snapshot IDs, for all instances
REM
REM For educational purposes only - no warranty is provided
REM Test thoroughly - use at your own risk
REM
set feedback off
set echo off
set verify off
set timing off
-- Set AWR_FORMAT to "text" or "html"
define AWR_FORMAT = 'text'
define DEFAULT_OUTPUT_FILENAME = 'awr-generate.sql'
define NO_ADDM = 0
-- Get values for dbid and inst_num before calling awrinput.sql
set echo off heading on
column inst_num heading "Inst Num" new_value inst_num format 99999;
column inst_name heading "Instance" new_value inst_name format a12;
column db_name heading "DB Name" new_value db_name format a12;
column dbid heading "DB Id" new_value dbid format 9999999999 just c;
prompt
prompt Current Instance
prompt ~~~~~~~~~~~~~~~~
select d.dbid dbid
, d.name db_name
, i.instance_number inst_num
, i.instance_name inst_name
from v$database d,
v$instance i;
-- Call the Oracle common input script to setup start and end snap ids
##?/rdbms/admin/awrinput.sql
-- Ask the user for the name of the output script
prompt
prompt Specify output script name
prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~
prompt This script produces output in the form of another SQL script
prompt The output script contains the commands to generate the AWR Reports
prompt
prompt The default output file name is &DEFAULT_OUTPUT_FILENAME
prompt To accept this name, press <return> to continue, otherwise enter an alternative
prompt
set heading off
column outfile_name new_value outfile_name noprint;
select 'Using the output file name ' || nvl('&&outfile_name','&DEFAULT_OUTPUT_FILENAME')
, nvl('&&outfile_name','&DEFAULT_OUTPUT_FILENAME') outfile_name
from sys.dual;
set linesize 800
set serverout on
set termout off
-- spool to outputfile
spool &outfile_name
-- write script header comments
prompt REM Temporary script created by awr-generator.sql
prompt REM Used to create multiple AWR reports between two snapshots
select 'REM Created by user '||user||' on '||sys_context('userenv', 'host')||' at '||to_char(sysdate, 'DD-MON-YYYY HH24:MI') from dual;
set heading on
-- Begin iterating through snapshots and generating reports
DECLARE
c_dbid CONSTANT NUMBER := :dbid;
c_inst_num CONSTANT NUMBER := :inst_num;
c_start_snap_id CONSTANT NUMBER := :bid;
c_end_snap_id CONSTANT NUMBER := :eid;
c_awr_options CONSTANT NUMBER := &&NO_ADDM;
c_report_type CONSTANT CHAR(4):= '&&AWR_FORMAT';
v_awr_reportname VARCHAR2(100);
v_report_suffix CHAR(5);
CURSOR c_snapshots IS
select inst_num, start_snap_id, end_snap_id
from (
select s.instance_number as inst_num,
s.snap_id as start_snap_id,
lead(s.snap_id,1,null) over (partition by s.instance_number order by s.snap_id) as end_snap_id
from dba_hist_snapshot s
where s.dbid = c_dbid
and s.snap_id >= c_start_snap_id
and s.snap_id <= c_end_snap_id
)
where end_snap_id is not null
order by inst_num, start_snap_id;
BEGIN
dbms_output.put_line('');
dbms_output.put_line('prompt Beginning AWR Generation...');
dbms_output.put_line('set heading off feedback off lines 800 pages 5000 trimspool on trimout on');
-- Determine report type (html or text)
IF c_report_type = 'html' THEN
v_report_suffix := '.html';
ELSE
v_report_suffix := '.txt';
END IF;
-- Iterate through snapshots
FOR cr_snapshot in c_snapshots
LOOP
-- Construct filename for AWR report
v_awr_reportname := 'awrrpt_'||cr_snapshot.inst_num||'_'||cr_snapshot.start_snap_id||'_'||cr_snapshot.end_snap_id||v_report_suffix;
dbms_output.put_line('prompt Creating AWR Report '||v_awr_reportname
||' for instance number '||cr_snapshot.inst_num||' snapshots '||cr_snapshot.start_snap_id||' to '||cr_snapshot.end_snap_id);
dbms_output.put_line('prompt');
-- Disable terminal output to stop AWR text appearing on screen
dbms_output.put_line('set termout off');
-- Set spool to create AWR report file
dbms_output.put_line('spool '||v_awr_reportname);
-- call the table function to generate the report
IF c_report_type = 'html' THEN
dbms_output.put_line('select output from table(dbms_workload_repository.awr_report_html('
||c_dbid||','||cr_snapshot.inst_num||','||cr_snapshot.start_snap_id||','||cr_snapshot.end_snap_id||','||c_awr_options||'));');
ELSE
dbms_output.put_line('select output from table(dbms_workload_repository.awr_report_text('
||c_dbid||','||cr_snapshot.inst_num||','||cr_snapshot.start_snap_id||','||cr_snapshot.end_snap_id||','||c_awr_options||'));');
END IF;
dbms_output.put_line('spool off');
-- Enable terminal output having finished generating AWR report
dbms_output.put_line('set termout on');
END LOOP;
dbms_output.put_line('set heading on feedback 6 lines 100 pages 45');
dbms_output.put_line('prompt AWR Generation Complete');
-- EXCEPTION HANDLER?
END;
/
spool off
set termout on
prompt
prompt Script written to &outfile_name - check and run in order to generate AWR reports...
prompt
--clear columns sql
undefine outfile_name
undefine AWR_FORMAT
undefine DEFAULT_OUTPUT_FILENAME
undefine NO_ADDM
undefine OUTFILE_NAME
set feedback 6 verify on lines 100 pages 45
This piece of code generates a spool file with consecutive snap ids between start snap and end snap. I want to modify it, such that it asks for an interval value and calculate start_snap and end_snap with that interval.
For eg.
If I give start_snap as 1400 and end_snap as 1404 with interval as 2, then it should give reports with 1400 to 1402, 1403 to 1404.
Regards,
Kaushal.

Prevent output of SPOOL from being wrapped

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;
/

Resources