SQLPLUS : set sqlformat insert : SP2-0158 - sql

I want to export all my datas as insert statement.
In Sql Developer, the command "set sqlformat insert" work very well... but when I want to use it on sqlplus, I have this error message : SP2-0158 unknown SET option "sqlformat"
This command work when it's use on a script but i've made a script :
spool /data/scripts/result/test.sql
set sqlformat insert;
select * from mytable;
spool off
I've try the same code on SQLdev and it works...
How can I use it correcly on sqlplus ?

sqlformat insert is NOT an sqlplus acceptable format, try it with sqlcl. It should work (and allow you to use the same setting as you can do in sqldev)

Related

How to use spool command in sql developer oracle

Dears,
I cannot use spool command. It is not working or i am not doing something right.
I am trying to save query result in txt file (tried also csv saving with select /*csv*/ * from table but it also did not work).
So what i wrote is:
set echo off
set trimspool on
spool 'C:\Users\username\Desktop\clobams\Test1.txt'
select pn, serial_number from stock ;
spool off;
And i am getting error when pressing execute statement ORA-00900:invalid SQL statement . Sql works fine - when i execute only that part,it gives me output to the screen. How should i save my output to the file?
I have already tried to remove set echo off and set trimspool on but none of these helped
this is what i have run on my sql developer:
spool C:\Users\**direcotory**\Desktop\old desktop\sql\Test1.txt;
select * from YOUR_TABLE;
spool off;
and i got output in file test1. you need to run all commands as script.

Executing sql file from another sql file

I have a .sql file with name Alter_table.sql which have the following code.
alter table mytable add newcolumn VARCHAR2(1);
I don't want to edit this file and add a spool command. However I need to execute Alter_table.sql by writing spool in another file (execute_sql.sql) which should look like the below. I am not sure of the correct syntax. Can anyone please help here?
SET SERVEROUTPUT ON
SET DEFINE OFF
SPOOL Alter_Table_STD_SOURCE.log
EXEC username/password#database `Alter_table.sql`
SPOOL OFF;
SET DEFINE ON
SET SERVEROUTPUT OFF
(Thanks to Alex Poole) :-)
You need to connect first, then run your .sql file in the wrapper script using the '#' sign or 'START' commands:
...
-- Connect if not already connected.
CONNECT username/password#database
#Alter_table.sql
...
I'm not sure its a good idea to keep login/password in a file but you need to take security into account.

How to pass a bash variable to sqlplus and then pass that output to another variable

So what I'm trying to do is to clear the audit logs of the PDB in an Oracle database. The name of the PDB can be different each time, so I cannot use tnsnames to sqlplus directly into the PDB to do this. I'm passing commands into bash and then passing those into a SQLPLUS command. Each of these work except for one and I can't seem to figure out how to get it to work.
My code is
AUDIT="DELETE FROM SYS.AUD$ WHERE NTIMESTAMP# < sysdate-30;"
FINDPDB="select pdb_name from dba_pdbs where pdb_name != 'PDB\$SEED';"
ALTER="alter session set container=$FINDPDB;"
sqlplus -S /nolog <<EOF1
connect / as sysdba
set echo off feedback off head off pages 0
set serveroutput on
$FINDPDB
$ALTER
$AUDIT
exit;
EOF1
The error I keep getting is
alter session set container=select pdb_name from dba_pdbs where pdb_name != 'PDB$SEED';
*
ERROR at line 1:
ORA-65015: missing or invalid container name
This tells me that it's not passing the output of the select statement to $FINDPDB, but rather the actual select statement itself.
Is there a way I can pass this value to the ALTER variable and have it alter the session and clear the sys.aud$ table?
The error I keep getting is
alter session set container=select pdb_name from dba_pdbs where pdb_name != 'PDB$SEED';
*
ERROR at line 1:
ORA-65015: missing or invalid container name
This tells me that it's not passing the output of the select statement to $FINDPDB, but rather the actual select statement itself.
I don't see why you would expect this to pass the output of the SELECT query into $FINDPDB. You're putting together a big long string which bash passes to the standard input of sqlplus and then writes to stdout the output from sqlplus. At no point is bash picking out certain lines of the sqlplus output and putting them into shell variables.
In fact, try adding echo $ALTER to your bash script before you call sqlplus. You will quite probably find that the output is
alter session set container=select pdb_name from dba_pdbs where pdb_name != 'PDB$SEED';
If so, then bash has already done the substitution you didn't want before you've even started sqlplus.
You seem to want bash and sqlplus to have some kind of back-and-forth dialog. I would give up on this approach. Instead of trying to put the PDB name into a shell variable, I would put it into a sqlplus substitution variable. I would try something like the following (not tested):
sqlplus -S /nolog <<"EOF1"
connect / as sysdba
set echo off feedback off head off pages 0
set serveroutput on
column pdb_name new_value pdb
select pdb_name from dba_pdbs where pdb_name != 'PDB\$SEED';
alter session set container = &pdb.;
delete from sys.aud$ where ntimestamp# < sysdate - 30;
exit;
EOF1
We use column pdb_name new_value pdb to set the substitution variable pdb to the next value to be selected from a column named pdb_name. We then run a select query to fetch the PDB name and hence store it in pdb. Once we've got this value in a substitution variable, we can then issue the alter session statement to change the PDB and finally the delete statement to delete data from the PDB.
I'm tempted to avoid the use of a PL/SQL block for this, as has been suggested in another answer. I would prefer that the delete statement is parsed after the PDB is changed as I would want to be sure that the data from the 'correct' PDB is being deleted. My concern with using PL/SQL for this is that the PL/SQL compiler would determine which table to delete from when the block is parsed, which would be before it runs the block, and hence before it executes the alter session statement to change the PDB. However, I don't know PDBs and CDBs in Oracle 12c well enough to say whether this is a genuine problem or unfounded nonsense.
I don't have access to a pluggable Oracle 12c database to run something like this against, so I can't tell you whether this script works. If not, hopefully it should give you an idea of where to go.
I have no Oracle instance at hand but I see two ways to do this :
Make many connections through SQL*Plus
First, to retrieve pdb_name.
Second, to set container and delete audits.
Uses a single SQL*Plus but uses two named pipes
One to send generated SQL commands
Second to read SQL*Plus output
As alternative way I should have used a "real" programming language (Ruby, Python, JavaScript) which are better dedicated to deal with data read from database.
EDIT: After some search, it mays be done in PL/SQL
DECLARE
v_pdb_name VARCHAR2(255);
BEGIN
SELECT pdb_name INTO v_pdb_name FROM dba_pdbs WHERE pdb_name != 'PDB\$SEED';
EXECUTE IMMEDIATE 'ALTER SESSION SET container='||v_pdb_name;
DELETE FROM sys.aud$ WHERE ntimestamp# < sysdate-30;
END;
/

Oracle SQL Developer - Spooling error

I am learning SQL at the moment, and am using Oracle SQL Developer.
Right now I am having an issue with the spool command.
I insert the file path and name the file but I keep getting an "unknown command" error.
spool C:\Users\user\Desktop\AAA_Task1\output.txt
set echo on
--drop table TESTTABLE;
create table TESTTABLE (TestCol int);
set echo off
spool off
I alternate between the create and drop statements for each test.
I run the and the table is created or dropped correctly, but I get a line one error "Unknown Command" and no text file is created.
I have attached a picture of a test command and the error.
If someone could point me in the right direction I would be grateful.
There is difference between run script and run statement, see here.
Use following commands and run script.
spool 'C:\Users\user\Desktop\AAA_Task1\output.txt'
set echo on
--drop table TESTTABLE;
create table TESTTABLE (TestCol int);
set echo off
spool off
Making the file path in quotes did not work for me in the Oracle database.
spool data.txt
set echo on
Query -- the query
set echo off
spool off
this will save the query and output to the data.txt file in the
"C:\Users\NELSON JOSEPH\AppData\Roaming\SQL Developer\data.txt" in this location likewise username varies for others.

Create a variable in Vertica

I am transitioning from SQL Server to Vertica. Is there any comparable way to create a variable?
Usually I do something like:
Define #myVariable int
Set #myVariable = select MAX(Field1) from myTable
I do not think Vertica allows variables, except if you are using vsql directly, but then vsql variables are very limited and will not do what you expect:
-- this will work
\set a foo
\echo :a
foo
-- this is not what you expect:
\set a NOW()
\echo :a
NOW()
\set a select max(id) from s.items()
\echo :a
selectmax(id)froms.items()
See for more information the vertica doc at https://my.vertica.com/docs/6.1.x/HTML/index.htm#2732.htm
You do not "create variables" in Vertica the same way you do not "create variables" in SQL Server. What you're trying to convert is a T-SQL script.
You can do the same in Vertica by creating Perl or Python or Java ... scripts running outside the database or writing a user defined function in C++ or R or Java running inside Vertica.
You can use :variable_name in Vertica for a user input variable. For example:
select date_time from table_1 where date_time between :start and :end
In above start and end are the variables. When you run the query, a dialog box opens prompting you to enter the values for start and end.
If you are using vsql, you can create variables that contain results of queries, though it is a bit convoluted:
Lets assume you start vsql with vsql -v INARG=33;
SELECT :INARG+1; -- Set up the query
\pset format u
\pset t -- Update output format to bare
\g `echo /tmp/dyneval` -- Eval the query and write into file
\set DYNARG `cat /tmp/dyneval` -- Set var from shell command output
\echo :DYNARG
So basically we write the query result into a file and read the file's contents into a variable.
You can use /tmp/dyneval-${PPID}_id instead of /tmp/dyneval, so you can ensure, that parallel executions wont alter each other. (PPID being the parent process's process ID, that is the vsql process's PID.)
The solution has some limitations:
assumes a linux env (echo, cat)
it changes the output formatting settings (\pset)