How   to  CD to another Directory when installing with sqlplus scripts...
pasko, April     02, 2003 - 8:31 am UTC
 
 
Hi Tom ,
How could i CD  to a Sub Directory  from my current  Directory while installing some packages using sql script which has ' @@ '  constructs in it ..
Example :
my_install.sql  has :
@@file1.sql
@@file2.sql
rem  i want to move to sub directory now to get another file
@@..\temp_dir\file3.sql  
rem  but the above apparently doesn't seem to work
is this possible or do i have to always specify a full path ?
Thanks in advance.
 
 
April     02, 2003 - 9:01 am UTC 
 
the @@ only works on a simple file name -- no relative paths.   
 
 
 
Is there a way to make @@ to work with relative path?
Chuan Sat, July      20, 2003 - 12:18 am UTC
 
 
Tom
  Your answer on @@ is very informative.  In your last follow up however you saying that @@ does not work on a relative path? 
   Is there a way at all to make it work with such path?  This is because the root of the relative path in this case may not always be the same, but the subdirectory that is the relative path does.  
For example
I am in c:\WorkDir calling
@@c:\InstallDir\Master.sql
Master.sql has..
@@Table.sql
@@View.sql
@@proc\proc1.sql
@@proc\proc2.sql
In this case, @@ will never find proc1.sql and proc2.sql because it is in proc not in InstallDir.  I can make it
@@InstallDir\proc\proc1.sql
@@InstallDir\proc\proc1.sql
However the problem is..the root dir. is not always InstallDir, it can be something else like InstallDir2.  If I move all the files to InstallDir2, the @InstallDir\proc\proc1.sql becomes immediately invalid.
- is there a another command or a way to make the @@ to work with such relative path?  Thanks
 
 
 
pseudo-relative path
finally_got_it, July      29, 2003 - 11:49 am UTC
 
 
In unix, I set the SQLPATH environment variable to
include the path to my  master script and the paths to the subdirectories as well.  I find that the @@./subdirectory syntax works when I do this.
I do something like this - 
setenv SQLPATH /auto/bcf/edi/data:/auto/bcf/edi/data/ins
I then run sqlplus from some other directory 
SQL> @crorder 
This executes crorder.sql, which happens to live in /auto/bcf/edi/data.  The script contains several calls like  this
@./ins/insbulklineitem
@./ins/prepacklineitem
which work fine.  If I remove the /auto/bcf/tst/edi/tst/data/ins subdirectory from the SQLPATH, sqlplus reports that it is unable to find insbulklineitem and insprepacklineitem.  It doesn't make a lot of sense to me, but it works which is all I am looking for.  Perhaps you can do something similar in Windows. 
 
 
 
Regarding & and &&
Charlotte, December  08, 2003 - 1:47 pm UTC
 
 
Thanks, Tom. This is something I can use every day. 
 
 
Suppress substitution?
Dennis, January   21, 2004 - 4:31 pm UTC
 
 
Is there a way to suppress the substitution output?
So that instead of getting this in a spooled log:
old   9: where owner ='&&1.UTIL')
new   9: where owner ='FINUTIL')
create synonym FINutil.DEMO_TRUNCATE for FINDAILY.DEMO_TRUNCATE;                                    
we could just get the sql statement and not have any old/new lines.
I am calling it by the following method:
@c:\quick_syn.sql FIN
I don't mind just running the spool and getting two nonsense errors, but it's been asked to see if I could eliminate that.     I was thinking of using accept and hide, but it wasn't working too well because it stops and wants to accept something that is typed in.
Is there any way to accomplish this?
Thanks,
Dennis 
 
January   21, 2004 - 5:59 pm UTC 
 
set verify off
stops the substitution "showing" from happening. 
 
 
 
Thanks!
Dennis, January   22, 2004 - 12:51 pm UTC
 
 
That was it.  Didn't know about the Verify set. 
 
 
Prompt Variable Fixed Length
denni50, June      02, 2005 - 10:25 am UTC
 
 
Hi Tom,
I have Sqlplus Batch Menu that I created to facilitate
user verification and update processes.
On one of the sql scripts that is called from the Batch
Menu Screen users have requested that the prompt variables
be made a fixed length so that they do not, inadvertently
add another digit, the number should be a fixed length(8):
SET TERM ON
Update batch
set status='P'
where batchno between &batch1 and &batch2;
commit;
....is there a way to format the prompts(&batch1 and &batch2) to a fixed length like when using Column Formatting:
 
Column columnname format a8.
thanks
 
 
June      02, 2005 - 5:08 pm UTC 
 
need more details -- what do you want to do when
a) input > 8
b) input < 8
(please tell me "fail" for (a), that is the only sensible thing isn't it?) 
 
 
 
prompt variable followup
denni50, June      03, 2005 - 8:45 am UTC
 
 
Tom...
just want to keep this as simple as possible.
If &batch is < 8 the application will raise an error
stating no such batch number exists. All batch numbers
are 8 digits in length. Users are requesting that the
&batch1 and &batch2 do not allow for more than 8 digits,
whether or not those digits are entered correctly is
subject to user data entry accuracy and verification.
 
I removed the commit; in the script and now prompt
the user to type in COMMIT; or ROLLBACK; in the event
an incorrect &batch1 and &batch2 are entered.
yesterday a user inadvertently entered &batch2 as 200124451
the intended &batch2 was 20012441....however there does
exist a batch 20012445(which resulted in being incorrectly updated)..the application truncated the last digit since the column datatype(in the batch table) is a number(8).
so all I really need is setting the prompt variable to
a fixed length, along with allowing users to either commit or rollback.
thanks..
ps: did some searching through the SQPlus reference manual
and internet searches and couldn't find anything on substitution variable lengths except for using DEFINE and
that uses a CHAR datatype.
 
 
June      03, 2005 - 8:51 am UTC 
 
ops$tkyte@ORA10G> @test
Enter x: 12345678
old   2:        if ( length('&x') <> 8 )
new   2:        if ( length('12345678') <> 8 )
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA10G> @test
Enter x: 123456789
old   2:        if ( length('&x') <> 8 )
new   2:        if ( length('123456789') <> 8 )
begin
*
ERROR at line 1:
ORA-20001: You lose
ORA-06512: at line 4
 
 
ops$tkyte@ORA10G> get test
  1  accept x prompt 'Enter x: '
  2  begin
  3     if ( length('&x') <> 8 )
  4     then
  5             raise_application_error( -20001, 'You lose' );
  6     end if;
  7* end;
  8
 
 
 
 
 
thanks Tom...
denni50, June      03, 2005 - 9:28 am UTC
 
 
was hoping to avoid using PL/SQL however in this case
it has it's merits.
:-)
 
 
June      03, 2005 - 10:01 am UTC 
 
ops$tkyte@ORA10GR2> @test
Enter x: 123
old   1: select case when length('&x') <> 8 then 1/0 end from dual
new   1: select case when length('123') <> 8 then 1/0 end from dual
select case when length('123') <> 8 then 1/0 end from dual
                                          *
ERROR at line 1:
ORA-01476: divisor is equal to zero
there, technically we avoided plsql ;) 
 
 
 
 
Tom...
denni50, June      03, 2005 - 11:44 am UTC
 
 
I decided to do it this way:
SET TERM ON
Update batch
set status='P'
where batchno between substr(&batch1,1,8) and substr(&batch2,1,8);
prompt Please type COMMIT or ROLLBACK;
--commit;
SQL> select substr(&batch1,1,8) from dual;
Enter value for batch1: 200124450000
SUBSTR(2
--------
20012445
this way whatever digits are added after the first 8 are
truncated..they just need to make sure the first 8 digits
are correct...if not then ROLLBACK;
 
 
 
June      03, 2005 - 12:42 pm UTC 
 
that just sounds wrong to me. 
 
 
 
Tom...
denni50, June      03, 2005 - 1:40 pm UTC
 
 
This is just a mechanism for users to validate or update
batches before posting data to tables. Before I created
the batch menu screen(see below)...they used to cut
and paste all the sql statements that were used for
verification. In the case I presented here users would actually type out the entire update statement.
When I came on board I asked them if they would like
me to create a SQLPLus Menu were they could select
a number, answer prompts and run the same sql scripts..
they were all..."you can do that???".
so I created this:
set serveroutput on size 1000000 
set echo off verify off trimspool on term on linesize 1000
cl screen
prompt ***************************************************
prompt * Select Batch Verification Processing Option:
prompt *  1.  Verify Client
prompt *  2.  Verify Appealcode
prompt *  3.  Verify Dollars and Count
prompt *  4.  Update Batch Status
prompt *  5.  Verify Batch Flags
prompt *  6.  Verify NULL Acknowledgement
prompt *  7.  Verify NOT LIKE Appealcode
prompt *  8.  Verify NULL GiftType
prompt *  9.  Verify T_Date
prompt * 10.  Verify Year
prompt * 11.  Verify IntCode ATL NATL DECD
prompt * 12.  Verify IntCode 998 UDAD
prompt * 13.  Exit
prompt ***************************************************
accept process prompt ">"
SET TERM OFF
STORE SET saved_settings REPLACE 
SET TERM ON
SET FEEDBACK OFF HEADING OFF 
SPOOL query.sql
select decode(&process,1,'START checkClient',2,'START checkAppealcode',
3,'START checkDollars_Count',4,'START upd_BatchStatus',5,'START check_BatchFlags',
6,'START NullAcknowledgement',7,'START checkAppealcodeNL',
8,'START checkGifttype_Null',9,'START checkT_Date', 10, 'START checkYear_Null',
11,'START checkIntcode',12,'START checkIntcode2',13,'prompt','Please Enter Correct Selection')
from dual;
SPOOL OFF
START saved_settings
START query
in the case I presented here:
**************************************************
* Select Batch Verification Processing Option:
*  1.  Verify Client
*  2.  Verify Appealcode
*  3.  Verify Dollars and Count
*  4.  Update Batch Status
*  5.  Verify Batch Flags
*  6.  Verify NULL Acknowledgement
*  7.  Verify NOT LIKE Appealcode
*  8.  Verify NULL GiftType
*  9.  Verify T_Date
* 10.  Verify Year
* 11.  Verify IntCode ATL NATL DECD
* 12.  Verify IntCode 998 UDAD
* 13.  Exit
**************************************************
>4
START upd_BatchStatus
Enter value for batch1: 20012445
Enter value for batch2: 20012445
1 rows updated.
Please type COMMIT or ROLLBACK
SQL> rollback;
Rollback complete.
SQL> 
 
users are happy...when they're happy, I'm happy!
This is not a situation where a more complex solution
is needed. 
 
 
 
June      03, 2005 - 5:04 pm UTC 
 
No, the automagical truncation scares me
if "I" typed in 9 digits, "I" would rather you fail the entire thing, not just truncate it.
I probably fat fingered a number *in the middle*, not just added a last digit.
that was my point. 
 
 
 
Point well Taken
denni50, June      04, 2005 - 1:41 pm UTC
 
 
Tom...
In the context and history of this situation I provided
automation as opposed to manually typing and hard coding
literals,which is just as prone to errors..if not more so.
I agree in an application setting better data entry
controls with user-defined error trapping mechanisms
would be in place..however this is an external preliminary
verification process that checks data before posting(
through the application) to base tables.
In the scenario I presented either one of two things
will occur:
1) number does not exist as entered therefore 0 rows updated.
2) incorrectly entered number does exist, wrong record
   got updated(whether error reflects >8 digits truncated or transposed numbers at any point or position between 1-8)
...in that event I empowered users to rollback.
They've been using this Menu system for 2+ years and
it is just recently that one user entered an additional
digit > 8 that resulted in an incorrect update that was
also being automatically committed through the sql script.
Users requested that they be given the choice to either
rollback or commit and that no more than 8 digits be
accepted via the prompt..that's what I gave them.
 
 
 
 
need help
A reader, October   10, 2005 - 5:11 am UTC
 
 
SQL> select * from dept;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
SQL> declare
i NUMBER := 1;
begin
   loop 
    insert into dept values('&deptno','&dname','&loc');
    i := i+1;
    EXIT WHEN i > 2; 
   end loop;
end;
/
Enter value for deptno: 50
Enter value for dname: MANAGEMENT
Enter value for loc: VIRGINIA
old   5:     insert into dept values('&deptno','&dname','&loc');
new   5:     insert into dept values('50','MANAGEMENT','VIRGINIA');
PL/SQL procedure successfully completed.
SQL> select * from dept;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
        50 MANAGEMENT     VIRGINIA
        50 MANAGEMENT     VIRGINIA
6 rows selected.
My doubt is why is that inputs are not prompted second time in the loop inspite of using &?
thanks
 
 
 
October   10, 2005 - 8:48 am UTC 
 
sqlplus is the thing that does this substitution - *NOT* plsql.
sqlplus sees "&deptno" and says - ah, they need a deptno, lets ask for it.  You gave it 50.  It sees &dname , &loc and does the same.
Then sqlplus submitted this VALID plsql block to the server for processing:
declare
i NUMBER := 1;
begin
   loop 
    insert into dept values('50','MANAGEMENT','VIRGINIA');
    i := i+1;
    EXIT WHEN i > 2; 
   end loop;
end;
/
PLSQL in the database cannot interact with the enduser - it is way over there on the server running, not interactively on your pc or whatnot.
 
 
 
 
sqlplus double at (@@) limitation
Jacek Szczepanski, January   13, 2006 - 7:48 am UTC
 
 
Thanks for explaining @@ limitation to work only for files but not directories.
Such information should have been a part of @@ documentation in SQL*Plus User's Guide and Reference.
It's also missing in the (otherwise fabulous) Oracle SQL*Plus: The Definitive Guide by Jonathan Gennick.
And Usenet/Google Groups/Orafaq seems to be silent about that. 
 
 
And if I want to run the script again?
Vinicius Pacheco, November  09, 2006 - 9:26 am UTC
 
 
Hi, Tom! Thanks for all unvaluable information in your site.
If I have a script using &&variables (a lot of repetitions) and need to run it again, but with other values, there is a way to clear all variables?
 
 
November  09, 2006 - 2:20 pm UTC 
 
exit
works very nicely.  short of that, you'd have to use undefine variable for each 
 
 
 
How to suppress & in a string
Sreekanth, January   24, 2007 - 3:40 am UTC
 
 
Hi Tom,
How to suppress the substitution for & if it is part of a string.  Like in this example.
SELECT mass_id FROM MASS WHERE RES_STMT = 'C5W&M70&LM7'
The column RES_STMT has the string.  But when I do it in SQL*PLUS to check for the existence of that string, i have been asked for substitution.
Your help is appreciated.