Ubuntu Shell Script for ORACLE db - oracle

I'm new to working with ORACLE over SSH (putty) terminal on an Ubuntu OS, my workstation has Windows OS.
I'm programming a shell that connects to the oracle DB then exports a table into a text file and then delete some records depending on a columnĀ“s value.
No SQL Plus is installed and this is a must because we need to simulate the infraestructure of our client.
This is part of the script's code:
#!/bin/bash
su oracle
export ORACLE_SID=ORA_SID
export ORACLE_HOME=/uxx/app/oracle/product/11.2.0/client_1
export TWO_TASK=[hostname]:[port]/[ORA_SID]
isql -v [db] [user] [pass] <<EOF
CREATE OR REPLACE DIRECTORY test AS '/xxx/yyy/';
DECLARE
f utl_file.file_type;
BEGIN
f := utl_file.fopen('TEST','sample.txt','W');
for s in (select * from [table]);
loop
utl_file.put_line(f,s);
end loop;
utl_file.fclose(f);
END;
quit;
exit
EOF
When I run the script I got the following output:
SQL> SQLRowCount returns -1
SQL> [S1000][Oracle][ODBC][Ora]ORA-06550: line 1, column 7:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
begin function pragma procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior
[ISQL]ERROR: Could not SQLExecute
SQL> [37000][Oracle][ODBC][Ora]ORA-00900: invalid SQL statement
[ISQL]ERROR: Could not SQLExecute
SQL> [S1000][Oracle][ODBC][Ora]ORA-06550: line 1, column 5:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
( begin case declare exit for goto if loop mod null pragma
raise return select update while with <an identifier>
<a double-quoted delimited-identifier> <a bind variable> <<
continue close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe purge
[ISQL]ERROR: Could not SQLExecute
SQL> [37000][Oracle][ODBC][Ora]ORA-00900: invalid SQL statement
[ISQL]ERROR: Could not SQLExecute
SQL> [37000][Oracle][ODBC][Ora]ORA-00900: invalid SQL statement
[ISQL]ERROR: Could not SQLExecute
SQL> [37000][Oracle][ODBC][Ora]ORA-00900: invalid SQL statement
Any help would be greatly appreciated.

It resulted SqlPlus was indeed installed on the system but since it has been years since the last time I worked on UNIX like system I didn't know how to make the application work.
I first exported the bin path to my looged session:
export PATH=$ORACLE_HOME/bin:$PATH
Then I could run the sql plus and use the spool tool.
sqlplus usr/pass
Now with SqlPlus I can just use the regular spool command.
Thanks all who helped.

Related

Oracle triggers error on sqldeveloper export script

I had built a few tables with sequences and triggers, since I need to share the script with my team at uni I did an export with sqldeveloper, now when I try to import/execute the resulted .sql I'm getting errors with triggers.
This is the error message:
"Error starting at line 250 in command:
CREATE OR REPLACE EDITIONABLE TRIGGER "TRG_ACCOUNTS"
BEFORE INSERT ON ACCOUNTS
FOR EACH ROW
BEGIN
SELECT SEQ_ACCOUNTS.NEXTVAL INTO :NEW.ACCOUNT_ID FROM DUAL
Error report:
SQL Command: editionable TRIGGER
Failed: Warning: execution completed with warning
Error starting at line 258 in command:
END
Error report:
Unknown Command
trigger "TRG_ACCOUNTS" altered."
This is the part of the script it's complaining about. I have a few other triggers and it's giving me the same error on all of them. I've checked how the triggers are created after executing the script, and all of them seem to be missing a semi colon and the "END;" at the end.
Example:
create or replace
TRIGGER "TRG_FL_AR"
BEFORE INSERT ON FLOOR_AREAS
FOR EACH ROW
BEGIN
SELECT SEQ_FL_AR.NEXTVAL INTO :NEW.FLOOR_AREA_ID FROM DUAL <-- missing ";" here
<missing "END;" here>
Could you please help me?
Thank you.
Try to put a back slash / after line 258 and check again

Dynamic query error "invalid character" [duplicate]

i got a little problem in Oracle. I try to create a sequence for generating IDs in a table that already has data in it. I try to use the following anonymous block.
declare y varchar2(2000);
BEGIN
SELECT 'CREATE SEQUENCE ID_SEQ MINVALUE 1 MAXVALUE 9999999999 START WITH ' || (max(ID)+1) || ' INCREMENT BY 1 CACHE 20;' INTO y FROM TEST_TABLE;
--dbms_output.put_line(y);
execute immediate y;
end;
I get the following error:
Error report:
ORA-00911: invalid character
ORA-06512: at line 5
00911. 00000 - "invalid character"
If I execute the value of the y variable it works perfectly. I'm using SQL Developer as input interface and working on a 11g r2 Oracle server. I found similar codes where 'INCREMENT BY' parameter were script generated. Can someone explain my error?
When you execute immediate, the command you run should not have a semi-colon on the end; that is a command separator in SQL Developer (and SQL*Plus, and other clients), not part of the SQL statement itself.
SELECT 'CREATE SEQUENCE ID_SEQ MINVALUE 1 MAXVALUE 9999999999 START WITH '
|| (max(ID)+1) || ' INCREMENT BY 1 CACHE 20' INTO y FROM TEST_TABLE;
This is shown in the examples for plain SQL. Just to help confuse you though, if you are using PL/SQL within the dynamic SQL, you do still need semi-colons appropriate to PL/SQL itself - though not the executing / you'd use to run it directly from a client. This is shown in other examples.

how to handle sql script from unix

I am actually calling an SQL script from Unix using the below code. The SQL script has millions of DML's which will be run on my database. The requirement is that if an DML fails then the script should abort with an exit code rather than skipping to the next DML. Currently,it is executing all the DML's without breaking at the DML that failed. We actually need more control on the script. How can we achieve this? Plz help.
SCRIPT BODY
#! /bin/sh
echo "Script started at `date`"
#************** Execute the extract sql on Staging database***************#
`sqlplus -s $CCBSTGID/$CCBSTGPASSWRD#$CCBSTGDBASE <<EOF
whenever sqlerror exit 2;
whenever error exit 3;
set termout on
set echo on
set serveroutput on
set pagesize 0
set linesize 500
set heading off
set verify on
set feedback on
spool output1.txt;
#DMLFile.sql
spool off;
quit;
EOF`
RC=$?
echo $RC
if [ ${RC} != 0 ]
then
echo "Script execution failed"
exit 1
fi
The problem is that you aren't wrapping the DML statements within PL/SQL blocks so the WHENEVER SQLERROR ... isn't working like you expect. Here is a test case demonstrating the issue.
-- File: dmlfile.sql
update a set name = 'A';
foo; -- erroneous command to cause error
update a set name = 'B';
Before...
C:\>perl wrapper.pl
1 row updated.
SP2-0042: unknown command "foo" - rest of line ignored.
1 row updated.
Oops, both updates statements executed; script did not exit after error.
After wrapping with BEGIN and END
-- File: dmlfile.sql
begin
update a set name = 'A';
foo; -- erroneous command to cause error
update a set name = 'B';
end;
/
Running it:
C:\>perl wrapper.pl
foo; -- erroneous command to cause error
*
ERROR at line 3:
ORA-06550: line 3, column 2:
PLS-00201: identifier 'FOO' must be declared
ORA-06550: line 3, column 2:
PL/SQL: Statement ignored
Also, I don't know of any command WHENEVER ERROR, perhaps you were thinking WHENEVER OSERROR ?
See previous answer: PL/SQL: is there an instruction to completely stop the script execution?
Try wrapping all of your DML in a BEGIN ... END block:
-- DMLFile.sql
BEGIN
-- your DML statements here
END;
/
or wrap each individual logical block of statements in a block.
-- DMLFile.sql
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK;
BEGIN
-- block 1
END;
/
BEGIN
-- block 2
END;
/
WHENEVER SQLERROR EXIT is a SQLPlus directive, not standard SQL, but is fairly portable; it works in SQLPlus, SQL Developer, Toad, PL/SQL Developer, SQLsmith and others.
An alternative would be to use some other GUI client around your DML or pass the whole script to a tool that can do batch mode. Toad will stop after one error and prompt you.
SQLPLUS couldn't parse the command so it never made it to SQL. The SP2-0042 error is a sqlplus error, so it doesn't get caught by the WHENEVER SQLERROR EXIT directive. Sadly, There's no equivalent SQLPLUSERROR directive....
However, starting in the 11g sqlplus (not the database), Oracle has provided a error logging facility that can be used to trap various errors.
SQLPLUS> set errorlogging on
I finally found the reference here: SQLPlus User Guide

Execute copy from command from plsq

How to execute copy from command inside a plsql block?
E.g. I have copy from test/test#test insert emp using select * from emp;
How can I call this in a plsql block? I have tried with
execute immediate 'copy from test/test#test insert emp using select * from emp';
However when I execute my script which has plsql block gives me
ORA-00900: invalid SQL statement
How can I resolve this issue
COPY is a SQL*Plus command. So it only works in the SQL*Plus client. Find out more.
EXECUTE IMMEDIATE is a PL/SQL command to run dynamic calls, and it only recognises SQL and PL/SQL.
"I am executing sqlscript from sqlplus"
Yes, but you are calling COPY in an anonymous block, so that's with a PL/SQL scope; which means PL/SQL and SQL only.
The way to do this is with a shell script. These are operating system dependent, but something like this would work on a Linux environment.
#!/bin/bash
echo Please enter local Username:
read USERNAME
echo "Please enter local Password:"
read -s PASS
SID=${ORACLE_SID}
if [ "${ORACLE_SID}" != 'TEST' ]
then
sqlplus -s -l $USERNAME/$PASS#$SID << EOF
copy from test/test#test insert emp using select * from emp
exit
EOF
else
echo "Can't copy from TEST to TEST"
fi
Obviously this is just a wild guess at what your program actually does, but I hope you can understand the principle.
In a plsql code if we directly use the command as follows shall serve the similar output
begin
insert into emp1 select * from emp;
end;
emp1 is target table
emp is source table
There are similar ask where one wants to create blank structure or structure with data for backup kindly of activity.Refer link https://oracle-concepts-learning.blogspot.com/2019/09/copy-table-structure-or-data.html
1) Creating blank structure from existing table
--Execute on sql prompt
begin
execute immediate 'create table emp1 as select * from emp where 1=2';
end;
--Execute on sql prompt
select count(1) from emp1;
2) Creating structure from existing table with data
--Execute on sql prompt
begin
execute immediate 'create table emp1 as select * from emp';
end;
--Execute on sql prompt
select count(1) from emp1;

run string as query in oracle

i got a little problem in Oracle. I try to create a sequence for generating IDs in a table that already has data in it. I try to use the following anonymous block.
declare y varchar2(2000);
BEGIN
SELECT 'CREATE SEQUENCE ID_SEQ MINVALUE 1 MAXVALUE 9999999999 START WITH ' || (max(ID)+1) || ' INCREMENT BY 1 CACHE 20;' INTO y FROM TEST_TABLE;
--dbms_output.put_line(y);
execute immediate y;
end;
I get the following error:
Error report:
ORA-00911: invalid character
ORA-06512: at line 5
00911. 00000 - "invalid character"
If I execute the value of the y variable it works perfectly. I'm using SQL Developer as input interface and working on a 11g r2 Oracle server. I found similar codes where 'INCREMENT BY' parameter were script generated. Can someone explain my error?
When you execute immediate, the command you run should not have a semi-colon on the end; that is a command separator in SQL Developer (and SQL*Plus, and other clients), not part of the SQL statement itself.
SELECT 'CREATE SEQUENCE ID_SEQ MINVALUE 1 MAXVALUE 9999999999 START WITH '
|| (max(ID)+1) || ' INCREMENT BY 1 CACHE 20' INTO y FROM TEST_TABLE;
This is shown in the examples for plain SQL. Just to help confuse you though, if you are using PL/SQL within the dynamic SQL, you do still need semi-colons appropriate to PL/SQL itself - though not the executing / you'd use to run it directly from a client. This is shown in other examples.

Resources