SQL query inside a SQL Script - sql

I have a SQL script, which spools data to a file.
Sample Existing SQL script:
whenever sqlerror exit failure rollback
spool test.txt
set serveroutput on
select * from emp;
spool off
/
But, I would like to write a SQL query in this script before spooling data.
I don't want to hardcode the name of the spooling file, so how could I get the file name from a table or lookup?
I want the code to be something like
var filename varchar2(30);
select fname into :filename from table where script = 'abcscript';
spool :filename
set serveroutput on
select * from emp;
spool off
/
Thanks.

COLUMN spool_file_name NEW_VALUE.spool_file_name NOPRINT
select fname spool_file_name
from table where script = 'abcscript';
SPOOL &spool_file_name
SET ECHO ON
select * from emp ;
SPOOL OFF
COLUMN spool_file_name CLEAR

Related

not able to export table into csv format

I am trying to export table into csv format as below:
SQL> desc test;
Name Null? Type
----------------------------------------- -------- ----------------------------
DN NUMBER(10)
DISCONNECT_DATE DATE
SQL> select DN ,DISCONNECT_DATE from test into OUTFILE '/tmp/data.csv';
select DN ,DISCONNECT_DATE from test into OUTFILE '/tmp/data.csv'
*
ERROR at line 1:
ORA-00933: SQL command not properly ended
could you please anyone help me to resolved above problem.
I got the answer if we are using sql plus then we need use spool to get data into csv format. Below is the steps ...(don't forget to spool off after execution of query. )
SQL> set colsep ,
SQL> set headsep off
SQL> set pagesize 0
SQL> set trimspool on
SQL> spool /tmp/data.csv
SQL> select * from test;
-----------------(we cant placed the data)
10 rows selected.
SQL> spool off

Oracle SQL, spool to a dynamic file name

I am trying to spool to a csv that contains the current_date in its name:
spool '\mydir\'||to_char(current_date,'YYYYMMDD')||'.csv';
SELECT /*csv*/* FROM mydata;
spool off;
However, I get an error:
SP2-0768: Illegal SPOOL command
Usage: SPOOL { <file> | OFF | OUT }
where <file> is file_name[.ext] [CRE[ATE]|REP[LACE]|APP[END]]
Is it not allowed? Is there a workaround?
The same error appears if I try using a substitution variable, which does not seem to be allowed either.
Here's an example of how I do it [you may need to fiddle around a bit (e.g. set heading off) to get it exactly how you want it]:
set echo off
set feedback off
set term off verify off head on
set linesize 200 pagesize 9999
set long 4000000
set serveroutput on
-- get instance name in file name
column DATE_YYYYMMMDDD new_val FILE_NAME noprint
Select to_char(sysdate, 'YYYYMMDD') DATE_YYYYMMMDDD from dual;
spool \temp\CSV_&FILE_NAME..CSV
select table_name || ',' || column_name from user_tab_columns;
spool off
set serverout off
col myspoolbase noprint new_value val_myspoolbase
select 'myfilename' myspoolbase from dual;
col log_date noprint new_value val_log_date
select to_char(sysdate,'yyyymmdd_hh24miss') log_date from sys.dual;
spool &&val_myspoolbase._&&val_log_date..log
select sysdate from dual;
spool off

Oracle Spool using Dynamic SQL

I'm trying to pass a dynamic SQL statement to spool out to a text file using SQL*Plus, but I can't seem to execute the select statement I'm generating.
set linesize 10000 pagesize 0 embedded on
set heading off feedback off verify off trimspool on trimout on termout off
set underline off
COLUMN gen_sql NEW_VALUE gen_sql_
SELECT 'SELECT * FROM USER_TAB_COLS WHERE ROWNUM < 10' gen_sql_ FROM DUAL;
SPOOL 'myfilename.csv'
EXECUTE IMMEDIATE &gen_sql_
SPOOL OFF
/
I can't seem to use EXECUTE IMMEDIATE. Is there another way to execute the results of the select statement??
MORE DETAIL:
I have a set of views whose output I'd like to generate as formatted CSV files. I'm using dynamic SQL to create the formatting essentially. I generate something similar to:
SELECT TRIM(col1)||','||TRIM(col2)...FROM {myview}
I'm using the following to generate it this way:
COLUMN gen_sql NEW_VALUE gen_sql_
SELECT 'SELECT ' || LISTAGG ('TRIM('||COLUMN_NAME||')', '||'',''|| ')
WITHIN GROUP (ORDER BY COLUMN_ID) gen_sql FROM...
Anyway, I'm able generate this SQL statement and store into a SQL*PLUS variable, but I just need to execute it after the SPOOL statement so that it will print to the file. I'm not sure how to execute it. Normal statements work, such as:
SPOOL 'myfilename.csv'
SELECT 1 col1 FROM DUAL;
SPOOL OFF
/
So, it would seem reasonable that I could something similar but executing the contents of my variable like:
SPOOL 'myfilename.csv'
--- RUN MY DYNAMIC SQL ----
SPOOL OFF
/
I think this is what you're trying to achieve:
set linesize 10000 pagesize 0 embedded on
set heading off feedback off verify off trimspool on trimout on termout off
set underline off
SPOOL myfilename.sql
SELECT 'SELECT table_name||'',''||column_name FROM USER_TAB_COLS WHERE ROWNUM < 10;' gen_sql_ FROM DUAL;
SPOOL OFF
spool results.csv
#myfilename.sql
SPOOL OFF
I.e. first you spool the results of your query into a file, and then once the spool is complete, you call the script you just created, spooling the results of that into a separate file.
I believe you'll find EXECUTE IMMEDIATE is a PL/SQL command, so cannot be used directly in SQL or SQL*plus.
http://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems017.htm
Also, SPOOL is a SQL*Plus command, and cannot be used in PL/SQL ..
So you have a problem there ;)
Can you step back a bit and explain what it is you're trying to do ?
What is the requirements you have?
First you need to construct a sql dynamically using spool.
And then execute it.
set echo off
set verify off
set feedback off
set linesize 256
set pagesize 0
set term off
SPOOL 'myscript.sql'
SELECT * FROM USER_TAB_COLS WHERE ROWNUM < 10;
SPOOL OFF
set colsep ,
SPOOL myfile.csv
#myscript.sql
SPOOL OFF

Getting the create table command used in oracle 11g

How can I get the create table command which is used to create a table in oracle 11g so that I can copy the command and run it in another database? Please help.
select dbms_metadata.get_ddl('TABLE', 'YOUR_TABLE_NAME_GOES_HERE')
from dual;
Try to spool the output of the below query,
SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name)
FROM USER_TABLES u;
Like,
set pagesize 0
set long 90000
set feedback off
set echo off
spool schema.sql
SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name)
FROM USER_TABLES u WHERE TABLE_NAME = '<your_table>';
spool off;
Reference: http://www.dba-oracle.com/oracle_tips_dbms_metadata.htm
Please use the below Query
select dbms_metadata.get_ddl('TABLE','YOUR_TABLE_NAME','YOUR_SCHEMA_NAME') from dual;
if you use SQL Developer, select the table name , and right click to choose Open Declaration and then Click SQL tab on the window that opens!

Table names, and loop to describe

Working in Oracle 10g. Easy way to list all tables names (select table_name from dba_tables where owner = 'me')
But now that I have the table names, is there an easy way to loop through them and do a 'describe' on each one in sequence?
You could query against DBA_TAB_COLUMNS (or USER_TAB_COLUMNS).
Nicolas.
Not sure you can do a describe from within PL/SQL. I just tried using execute immediate 'describe some_table', that doesn't work either. Your next choice would be to query DBA_TAB_COLUMNS, or create a new file with all your describe statements (using dbms_output from pl/sql and spool to create the file) and then execute that file. Maybe like this:
spool temp_file.sql
BEGIN
/*or you could have a loop here with as many put_lines as you need, it will all end up in the new script file.*/
dbms_output.put_line('describe some_table');
END;
/
spool off
#temp_file.sql
/*I have not actually tried running this code, beware syntax errors!*/
You can do this in PL/SQL using DBMS_METADATA.GET_DDL, e.g. (example taken from docs):
SET LONG 2000000
SET PAGESIZE 0
SELECT DBMS_METADATA.GET_DDL('TABLE','EMP','SCOTT') FROM DUAL;
login with the user and then run the following commands, first file will contain the describe commands and the second file will be the desired file containing all the descriptions of all tables for logged in user
spool desctables.sql
select 'describe '||table_name||';' from user_tables;
spool off
spool alltables.txt
#desctables.sql
spool off
I'd recommend querying dba_tab_columns, as N. Gasparotto suggested, but if you really want describe output then create a file mulit-describe.sql with the following:
set pagesize 0
set termout off
set feedback off
set verify off
spool mdtmp.sql
select 'describe ' || owner || '.' || table_name
from dba_tables
where OWNER = upper('&1')
/
spool off
set termout on
#mdtmp.sql
Within SQL*PLUS run by:
#multi-describe ME