How to rollback automatically if script having error in Oracle sql plus - oracle

I need to execute the multiple script having one master sql file. Whenever I used to execute the master calling script named as calling_test.sql if anything error comes need to be rollbacked.
sqlplus USERNAME/PWD#SIR_NAME;
##calling_test.sql
here is content of calling_test.sql script.
SET echo ON;
SET define ON;
SET scan ON;
define PATH =/krishna/test
define AB_SCHEMA=AIM
spool Test_incremental.log
SET define ON;
##&&PATH/AUG/2019-08-28/test1.sql
SET define ON;
##&&PATH/AUG/2019-08-29/test2.sql
SET define ON;
##&&PATH /AUG/2019-08-30/test3.sql
SET define ON;

The scrip should contain something like this:
whenever sqlerror exit rollback
Example:
SQL> create table test (col number);
Table created.
SQL>
SQL script (named p.sql)
whenever sqlerror exit rollback
insert into test values (100);
insert into test values ('A');
Calling it:
M:\>sqlplus scott/tiger#orcl #p.sql
SQL*Plus: Release 11.2.0.1.0 Production on ╚et Ruj 26 13:38:50 2019
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
1 row created.
insert into test values ('A')
*
ERROR at line 1:
ORA-01722: invalid number
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
M:\>
Result:
SQL> select * From test;
no rows selected
SQL>

You can rollback the actions from called scripts, but in addition to WHENEVER command you must also SET AUTOCOMMIT OFF. Normally when Sqlplus exits a script invoked in a separate file it commits. However the preceding overrides that action. See below: (save each script to the indicated file.)
---------------------------------------------------------------------------- -- script mst_0.sql
create table multi_script_test( id integer, description varchar2(50));
insert into multi_script_test values( 0, 'Initial before script.');
commit;
-- script mst_1.sql
insert into multi_script_test values( 1, 'Insert from script mst_1');
-- script mst_2.sql
insert into multi_script_test values ( 2, 'Insert from script mst_2');
-- script mst_3.sql
insert into multi_script_test values ( 3/0, 'oops');
-- script mst_4.sql
insert into multi_script_test values ( 4, 'Insert from script mst_4');
-- main script mst_main.sql
set echo on
set autocommit off
whenever sqlerror continue rollback
##c:/so/ora/mst_0.sql
##c:/so/ora/mst_1.sql
##c:/so/ora/mst_2.sql
-- following should display rows 0, 1, 2
select * from multi_script_test;
-- generate error and due to whenever directive 'rollback' discard rows 1,2
#c:/so/ora/mst_3.sql
-- continue script processing, also due to whenever directive 'contunue'
#c:/so/ora/mst_4.sql
commit;
----------------------------------------------------------------------------
sqlplus -- complete the signon
-- run main script
#mst_main
-- following show show display 0, 4
select * from multi_script_test;
exit

Related

How can I drop and re-create a pluggable database in Oracle DB 18c XE? [duplicate]

I'm trying to execute a script on SQL PLus, it's simple.
SET serveroutput ON;
DECLARE
mode NUMBER(1) := 1;
IF (mode = 1) THEN
prompt 'HERE'
END IF;
prompt 'fim'
I call the script from SQLPlus using sqlplus user/pw#db and #myscript.sql after a successful connection. But the output is strange for me:
Conectado a:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> #myscript.sql
9
10
11
And it continues to print this sequence indefinitely.
What am I doing wrong?
From your edited question... you have to terminate the PL/SQL block with a / on a new line to make it end and run, otherwise SQL*Plus will keep prompting for more lines of code (which is the numbers you're seeing). The documentation shows how to run PL/SQL blocks. And prompt is a SQL*Plus command so you can't use it inside a PL/SQL block. You also don't have your block syntax right:
SET serveroutput ON;
DECLARE
mode NUMBER(1) := 1;
BEGIN
IF mode = 1 THEN
DBMS_OUTPUT.PUT_LINE('HERE');
END IF;
END;
/
prompt fim
You cannot use sqlplus command in plsql.We can use dbms_output instead which will display the output in SQL prompt
SET serveroutput ON;
DECLARE
mode NUMBER(1) := 1;
BEGIN
IF (mode = 1) THEN
dbms_output.put_line('HERE');
END IF;
dbms_output.put_line('fim');
END;
/
Go to your oracle home Oracle\product\<version>\client_2\sqlplus\admin\glogin.sql and add the following lines to enable printing globally,
SET ECHO ON;
SET TERM ON;
WHENEVER SQLERROR EXIT FAILURE ROLLBACK;
SET DEFINE OFF;

Import data from file.txt to table Oracle SQL using PL/SQL

I'm trying to read a file of type txt from c:\Dir and insert the content on the table Oracle Sql
set SERVEROUTPUT ON
CREATE OR REPLACE DIRECTORY MYDIR AS ' C:\dir';
DECLARE
vInHandle utl_file.file_type;
eNoFile exception;
PRAGMA exception_init(eNoFile, -29283);
BEGIN
BEGIN
vInHandle := utl_file.Fopen('MYDIR','attachment.txt','R');
dbms_output.put_line('The File exists');
EXCEPTION
WHEN eNoFile THEN
dbms_output.put_line('The File not exists');
END;
END fopen;
/
i have the file not exists but i have this file
I don't know whether space you have in front of the directory name in the first statement you posted makes difference (or is it just a typo), but - nonetheless, here's how it is usually done.
Create directory on hard disk:
C:\>mkdir c:\dir
Connect to the database as SYS (as it owns the database, as well as directories); create directory (Oracle object) and grant privileges to user which will use that directory:
C:\>sqlplus sys as sysdba
SQL*Plus: Release 11.2.0.2.0 Production on ╚et O×u 5 18:34:43 2020
Copyright (c) 1982, 2014, Oracle. All rights reserved.
Enter password:
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
SQL> create or replace directory mydir as 'c:\dir';
Directory created.
SQL> grant read, write on directory mydir to scott;
Grant succeeded.
SQL>
You don't need this, as you already have the file; I'll create it by spooling table contents.
SQL> connect scott/tiger
Connected.
SQL> spool c:\dir\example.txt
SQL> select * From dept;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> spool off;
SQL> $dir c:\dir\*.txt
Volume in drive C is OSDisk
Volume Serial Number is 7635-F892
Directory of c:\dir
05.03.2020. 18:39 539 example.txt
1 File(s) 539 bytes
0 Dir(s) 290.598.363.136 bytes free
SQL>
Finally, reusing code you wrote:
SQL> set serveroutput on
SQL>
SQL> DECLARE
2 vInHandle utl_file.file_type;
3 eNoFile exception;
4 PRAGMA exception_init(eNoFile, -29283);
5 BEGIN
6 BEGIN
7 vInHandle := utl_file.Fopen('MYDIR','example.txt','R');
8 dbms_output.put_line('The File exists');
9 EXCEPTION
10 WHEN eNoFile THEN
11 dbms_output.put_line('The File not exists');
12 END;
13 END fopen;
14 /
The File exists
PL/SQL procedure successfully completed.
SQL>
Works properly (congratulations, you wrote code that actually works!).
So, what have you done wrong?
as I said, space in front of c:\dir: CREATE OR REPLACE DIRECTORY MYDIR AS ' C:\dir';
database isn't on your computer but on a separate database server
it means that you probably created directory, but it points to c:\dir directory on the database server, not your own PC!
As Boneist commented, it is possible to create a directory (Oracle object) on computer which is NOT a database server, but that's not something we usually do. If you opt to choose this option, you'll have to use UNC (Universal Naming Convention) while creating directory.
Another option you might want to consider is to use SQL Loader. It is an operating system utility, installed along with the database or (full, not instant) client software. Its advantage is that it runs on your local PC (i.e. you don't have to have access to the database server) and is extremely fast. You'd create a control file which tells Oracle how to load data stored in the source (.txt) file.
Another option, which - in the background - uses SQL Loader, is to use an external table. It is yet another Oracle object which points to the source (.txt) file and allows you to access it using a simple SQL SELECT statement. Possible drawback: it still requires access to the Oracle directory (just like your UTL_FILE option).

Pass substitution variable to nested script

I have a situation where I have a number of scripts that I need to run consecutively under the one connection. Some of the scripts require human input at runtime. The way I have organised this is that I have a Windows batch file which prompts the user for the required parameters. That batch file then passes the acquired parameter values to the SQL script.
The problem is that the variable values aren't getting to the nested script. If I bypass the intermediate script it works fine. It seems as though the problem is in proxying the values to the second.
See below for a compelte test case. In my example I am only calling one nested Script (Script1.sql). However, in a real world scenario I would potentially have multiple of these scripts.
Create Table
CREATE TABLE TEST_TABLE
(
TEST_ID NUMBER,
CREATED_BY VARCHAR2(100 CHAR)
)
LOGGING
NOCOMPRESS
NOCACHE
RESULT_CACHE (MODE DEFAULT)
NOPARALLEL
MONITORING;
SET DEFINE OFF;
Insert into TEST_TABLE
(TEST_ID, CREATED_BY)
Values
(1, 'FirstUser');
Insert into TEST_TABLE
(TEST_ID, CREATED_BY)
Values
(2, 'SecondUser');
Insert into TEST_TABLE
(TEST_ID, CREATED_BY)
Values
(3, 'ThirdUser');
COMMIT;
Windows Batch File (TEST_BAT.bat)
:begin
#ECHO oFF
cls
set /p SID=DB_SID:
set /p USER=USER:
set /p USERPASS=USER PASS:
set /p NEW_USER_NAME=NEW USER NAME:
ECHO %SID%
ECHO %USER%
sqlplus %USER%/%USERPASS%#%SID% #TEST_SCRIPTS.sql %NEW_USER_NAME%
ECHO.
Master SQL Script (TEST_SCRIPTS.sql)
SET PAGESIZE 100
SET DEFINE OFF
SET SCAN OFF
SET FEEDBACK ON
SPOOL INSTALL_LOG.txt
#'Script1.sql' &1
SET FEEDBACK OFF
Nested Script 1 (Script1.sql)
SET PAGESIZE 100
SET DEFINE OFF
SET SCAN OFF
SET FEEDBACK ON
UPDATE TEST_TABLE SET CREATED_BY='&1';
COMMIT;
So, in summary - what am I doing wrong in getting the substitution parameter to the nested Script
I'm not entirely sure from your post whether the problem was that the script prompts for &1 to be input, or whether the value &1 is being written for CREATED_BY instead of the provided command-line arg.
If the latter, this problem may be related to using SET DEFINE OFF prior to accessing the arg rather than the structure of the scripts themselves. (By the way SET SCAN is obsolete).
Using your example table and scripts unaltered, I get the below (with sql-plus 12.2):
sqlplus myuser/mypass#mydatabase #TEST_SCRIPTS.sql VOLTRON
SQL*Plus: Release 12.2.0.1.0 Production on Wed May 31 12:58:46 2017
3 rows updated.
Commit complete.
SELECT * FROM TEST_TABLE;
TEST_ID CREATED_BY
1 &1
2 &1
3 &1
But, if one drops the SET DEFINE OFF (and SET SCAN OFF), the substitutions take place, as below:
sqlplus myuser/mypass#mydatabase #TEST_SCRIPTS.sql VOLTRON
SQL*Plus: Release 12.2.0.1.0 Production on Wed May 31 13:11:53 2017
old 1: UPDATE TEST_TABLE SET CREATED_BY='&1'
new 1: UPDATE TEST_TABLE SET CREATED_BY='VOLTRON'
3 rows updated.
Commit complete.
Now the replacement has been passed through into the inner script.
SELECT * FROM TEST_TABLE;
TEST_ID CREATED_BY
1 VOLTRON
2 VOLTRON
3 VOLTRON

Using dollar sign in sqlplus spool file

How to use file name with dollar sign (ie, '$') in unix like below
SQL> spool DIR$work.sql
SP2-0332: Cannot create spool file.
and i tried like below
SQL> spool DIR\$work.sql
SP2-0332: Cannot create spool file.
SQL> spool 'DIR\$work.sql'
SP2-0332: Cannot create spool file.
SQL> spool 'DIR$work.sql'
SP2-0332: Cannot create spool file.
I couldn't succeed in any way to create such file in oracle.
I have oracle 11g version.
In windows sqlplus it works fine.
You can use the set escchar setting to stop Oracle interpreting the dollar sign:
SQL> show escchar
escchar OFF
SQL> spool /tmp/$work.sql
SP2-0332: Cannot create spool file.
SQL> set escchar $
SQL> spool /tmp/$work.sql
SQL>
You are now spooling to that file name.
SQL> select * from dual;
D
-
X
1 row selected.
SQL> spool off
SQL> exit
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
...
$ cat /tmp/\$work.sql
SQL> select * from dual;
D
-
X
1 row selected.
SQL> spool off
Also see My Oracle Support document 761384.1 for more information.

PL SQL output is not getting displayed

I have fairly simply code ..running in Oracle Virtualbox. However for some reason it is not displaying pl/sql output.
Here is code snippet
SQL> set serveroutput on
SQL> list
1 Create or Replace procedure mytz
2 IS
3 v_mytz TIMESTAMP WITH TIME ZONE DEFAULT '2013-05-05 12:00:00 AM';
4 BEGIN
5 DBMS_OUTPUT.PUT_LINE ('Default timestamp is ' );
6* end mytz ;
SQL> /
Procedure created.
SQL>
Is there anything I need to do special to see the output on SQL prompt ?
You have to actually run the procedure, not just create it, e.g.:
set serverputput on
exec mytz;
The set serveroutput SQL*Plus command has to be in the session the procedure is executed, not the one where it is created (if they are different).
You are not showing the value of your variable at the moment; maybe you wanted this?
dbms_output.put_line('Default timestamp is: ' || v_mytz);

Resources