I have 4 Database connection in SQL developer(oracle). At evening I have to regularly run some scripts in all the 4 connection on same server. Is there is any shortcut that I run script only once and is reflected in all connection which is connected to some DB.
(NOTE: All the 4 connection will hold exactly same info.)
Can anyone suggest how to do this?
Here's how I do that: using the command prompt capabilities, not GUI. The only prerequisite is to have SQL*Plus installed on your computer.
For example, create SQL script you're about to run and save it into C:\Temp directory; let's name it "my_script.sql". It can contain both SQL and PL/SQL (don't forget to terminate it with a slash in that case!).
Here's how it should look like:
connect &2
spool &1
set echo on
set define off
-- Your SQL statements go here:
select to_char(sysdate, 'dd.mm.yyyy hh24:mi') vrijeme from dual;
begin
pkg_payments.p_gimme_my_money;
commit;
end;
/
-- End of your SQL statements
spool off
exit
Then create a DOS batch script, let's name it "run_my_script.bat" and put such a code in there:
#echo on
set SCRIPT=C:\Temp\my_script.sql
set SCRIPT_LOG=C:\Temp\my_script
if not exist %SCRIPT% goto END
start sqlplus.exe /nolog #%SCRIPT% %SCRIPT_LOG%.site_1.log "username_1"/"password_1"#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_1_name)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=service_name_1)))
start sqlplus.exe /nolog #%SCRIPT% %SCRIPT_LOG%.site_2.log "username_2"/"password_2"#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_2_name)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=service_name_2)))
start sqlplus.exe /nolog #%SCRIPT% %SCRIPT_LOG%.site_3.log "username_3"/"password_3"#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_3_name)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=service_name_3)))
start sqlplus.exe /nolog #%SCRIPT% %SCRIPT_LOG%.site_4.log "username_4"/"password_4"#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=host_4_name)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=service_name_4)))
:END
As you can see, it
sets local variables (SCRIPT, which points to a .SQL file you
created) and SCRIPT_LOG which contains log information about script's
execution)
invokes SQL*Plus (in parallel; if you want them to execute
serially, just remove the START keyword), connecting to each database
and running the script
The simplest way to test it is to double-click the .BAT file; it'll open 4 "black" command prompt windows and terminate them once the SQL script finishes its job. Check the LOG files!
When you're satisfied with the outcome, schedule .BAT file's execution in Task Scheduler so that they are executed regularly & automatically.
That would be all, I presume.
Related
I am quite new to batch scripting, and I am trying to run multiple sql files, which in turn may contain multiple sql DML/DDL queries from bat file. The output files must contain all the queries being executed and the query output. Unlike this example , I don't have spool command inside my sql file, and I can not edit the input sql files. The following command works for me in ksh file (thanks to here-document):
$sqlplus /nolog <<! >>$sqlLogs.lst
connect $USERNAME/$PASSWORD#${DBNAME}
set echo on timing on
spool ${SCRIPTRUNFILE_SPOOL}
select name from v\$database;
#${SCRIPTRUNFILE};
spool off
exit
!
I want the exact same in Windows bat file. I have tried using ^. I can't do combine all sql files into one, as I need logging for each sql file into different file. My attempt at the bat file script is as follows and I have played around this much, and it fails with spool command not recognized. I also prefixed below commands with sqlplus, but still unable to achieve something like above ksh file:
sqlplus -s username/pwd#DBName >> sqlLogs.lst
set echo on timing on
spool %RUNFILENAME%.lst
#%RUNFILENAME% > %RUNFILENAME%.lst
select name from v\$database;
spool off
quit
Following logic executes my scripts but does not log the query being executed. Also, I don't want to connect twice to the database.
echo select name from v$database; | sqlplus -s username/pwd#DBName >> sqlLogs.lst
echo quit | sqlplus -s username/pwd#DBName #%SCRIPTRUNFILE%>> %SCRIPTRUNFILE_SPOOL%.lst
Can someone here please help to spool to a file where I can log the queries as well, while maintaining a single DB Connection?
Pass your immediate SQL*Plus commands to your sqlplus via stdout, grouped together by Windows' ( and ) symbols...
(
echo.set echo on timing on
echo.spool %SCRIPTRUNFILE_SPOOL%
echo.select name from v$database;
echo.#%SCRIPTRUNFILE%
echo.spool off
echo.exit
) | sqlplus -s %USERNAME%/%PASSWORD%#%DBNAME% >> sqlLogs.lst
We are using CA Workload Control Center (Autosys) to run a windows batch file which calls another batch file which calls SQLPlus with the following:
sqlplus username/password %1 %2 %3
Since this is all being done remotely I cannot see what is actually happening on the server.
I am wondering if the sqlplus file exists but has invalid syntax (like referring to non-existent table) will the sqlplus prompt exit and return back to the batch file?
The reason I ask is because I am looking at the log file from Autosys and it shows that SQLPlus call was made, it prints out ERROR AT LINE 2: Invalid Table, but then it does not show any other activity with the batch script after that where there are multiple echoes and file copies etc. It seems as though it is not exiting SQLPlus perhaps?
Is there a parm I need to pass to SQLPlus to tell it to exit SQLPlus and return back to the calling script after running a SQL script if it fails?
Edit: We are using "WHENEVER SQL ERROR" inside of our SQL files as well and the log file does show this:
Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
But I am still expecting that it should continue with the rest of the Batch script but its not, above is the last that Autosys shows in the log
See SQLPlus instruction WHENEVER SQLERROR, it describes in Oracle docs:
http://docs.oracle.com/cd/B19306_01/server.102/b14357/ch12052.htm
Found the solution SO Post:
You can do sqlplus -l test/Test#mydatabase #script.sql; the -l flag means it will only try to connect once, and if it fails for any reason will exit instead of prompting. Look at the output of sqlplus -?, or see the documentation.
the below picture shows what gets returned when I run sqlplus in shell
but when I run this from the "run" command:
powershell.exe -noexit c:\sqltriggers\voicetrigger2.ps1
with voicetrigger2.ps1 as this:
$(sqlplus user/pass#OMP1 '#C:\sqltriggers\VOICEBLOCKTRIG.SQL');
I get this:
I should expect a 3 back. The issue is, I try to set that as a variable, and if the integer is greater than zero, run a BAT file. But I don't think the SQLPlus is returning JUST an integer value. I think its actually returning this:
count(*)
3
How do I get it to just return the integer value from the SQLplus command?
SQL*Plus isn't returning anything, it's displaying the result of the query on standard output. To get the direct call to only show 3 you can set heading off in the SQL script, and also call SQL*Plus with the -s flag to suppress the banner. You probably also want an exit at the end of the SQL script so it doesn't stay sitting at the SQL> prompt.
The same applies to the powershell call, but there's something else going on there; the 17 is a line number which means it's waiting for more input and hasn't executed the commands in the SQL script, which suggests either a query without a terminating ; or /, or a PL/SQL block without a terminating /. But if it's exactly the same SQL you ran in the first example then that is a bit odd as they should behave the same. You should add the SQL script contents to the question to see what might be wrong.
The only thing I can think of that would change behaviour like that is if you had a login.sql that includes a set sqlterminator command, but you'd have to be picking up different login.sql files from the two calls... which is plausible if powershell has its own environment variables, perhaps.
It won't work this way. As Alex mentioned, sqlplus doesn't return anything as a function - it only writes whatever output you generate to standard output.
You can have variables in sqlplus, but there is no easy way to pass them to host environment. The only way I can think of is to use spool command to generate another batch file, which will actually set your host variables, and then process them the way you want in your host script.
Something like this:
16:30:20 SYSTEM#sandbox> get host.sql
1 SET VERIFY OFF TRIMSPOOL ON TERMOUT OFF HEADING OFF LINESIZE 4000 PAGES 0 FEEDBACK OFF timing off
2 spool s:\.tmp\host.ps1
3 select '$env:MY_VAR="'||dummy||'"' from dual;
4 spool off
5* exit
16:30:25 SYSTEM#sandbox> #host.sql
Disconnected from Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production
PS S:\.tmp> cat host.ps1
$env:MY_VAR="X"
PS S:\.tmp> .\host.ps1
PS S:\.tmp> $env:my_var
X
PS S:\.tmp>
sqlplus -s /nolog <<EOF > query_result.txt
set heading off feedback off pagesize 0 linesize 30000 trimout on ;
select 5 from dual;
exit;
EOF
for i in `cat query_result.txt `
do
exit $i
done
try adding SET HEADING OFF in the beginning of your file. Check this answer (check the second best voted answer)
i have an Oracle scheduler job that run an executable shell script in Solaris environment. Job runs every 2nd Sunday each month, it runs in status failed in Scheduler Job log with error code : ORA-27369
here is my shell script :
#!/bin/bash
ORACLE_HOME=/app/oracle/10g;
export ORACLE_HOME;
ORACLE_SID=IBSDB;
export ORACLE_SID;
edate=`date "+%Y%m%d"`; export edate;
$ORACLE_HOME/bin/sqlplus "/ as sysdba" #/app/oracle/script/alter_all_index.sql
this shell script run sqlplus and execute alter_all_index.sql. alter_all_index.sql creates 2 file via spool command. first is ALTER_INDEX_REBUILD.sql, this file contain query to rebuild all index. and the second file is LOG_ALTER_INDEX_REBUILD.txt to store any error occurs while executing ALTER_INDEX_REBUILD.sql here is the code of alter_all_index.sql
set wrap off
set linesize 1000
set feedback off
set pagesize 0
set verify off
set termout off
spool ALTER_INDEX_REBUILD.sql;
prompt set linesize 1000
prompt set pagesize 0
prompt spool LOG_ALTER_INDEX_REBUILD.txt
PROMPT ------------------ START FROM HERE ---------------
--prompt varID nvarchar2(40):=sys_guid();;
--prompt insert into PCB_AGCM.QUERY_HK_MONITOR (ID, TASK_NAME, START_TIME, END_TIME, STATUS) values(varID, 'REBUILD INDEX', to_char(sysdate, 'Dy DD-Mon-YYYY HH24:MI:SS'), null, 'STARTING');;
--prompt commit;;
prompt ------------------ execute GCM_AGCM --------------
select 'ALTER INDEX '||owner||'.'||INDEX_NAME||' REBUILD ONLINE;'
from all_indexes where owner like 'PCB_AGCM%';
PROMPT ------------------ END OF SCRIPT ----------------------
--prompt update PCB_AGCM.QUERY_HK_MONITOR set end_time=to_char(sysdate, 'Dy DD-Mon-YYYY HH24:MI:SS'), status='COMPLETED' where ID = varID;;
prompt commit;;
prompt exec PCB_AGCM.GATHER_SCHEMA_STATS();;
PROMPT /
PROMPT ------------------- END OF SCRIPT ----------------------
prompt spool off
SPOOL OFF;
##ALTER_INDEX_REBUILD.sql
before the job run, both ALTER_INDEX_REBUILD.sql and LOG_ALTER_INDEX_REBUILD.txt are exist generated from previous manual run.
when i tested via Oracle Scheduler Job. first it run well, and i look its session through TOAD->session browser, it works well, query rebuild index was running, but after the last index done, job ended with error ORA-27369: job of type EXECUTABLE failed with exit code: Not owner.
i examine all the script. both ALTER_INDEX_REBUILD.sql and LOG_ALTER_INDEX_REBUILD.txt is not updated, Spool command will create and replace if existed by default, their last modification date is 13 April 2013. it should have changed into 9 May 2013.
i come with a conclusion, that there is a problem with spool command, but i got no idea how to solve this, i thought that it might concern their ownership and permission but both file owned by oracle. anyone got any idea why and how to solve this ?
i have browsed about ORA-27369 but none gives me any hints so far.
sincerely
There are a few Big Questions to ask about this:
Why run as an external job a sql*plus script that you could just run as a pl/sql procedure? As a general rule, if you do not need to involve the operating system in a task, then don't do it. Code kept on the file system is not backed up with the database and is more prone to error through connection problems or Some Damn Fool Just Deleting It.
Code like the index rebuild ought to be a procedure with code such as:
for indexes in (select owner,
index_name
from all_indexes
where owner like 'PCB_AGCM%'
order by owner,
table_name)
loop
sql := 'alter index '||indexes.owner||'.'||indexes.index_name||' rebuild online';
execute immediate sql;
end loop
Why are you regularly rebuilding all of your indexes? If you get an immediate measurable benefit to it then it's because you have compacted your indexes, but you're then going to incur more overhead through the index growing back to it's natural size. See many entries on Richard Foote's blog for more information.
As far as I know, external programs launched by DBMS_SCHEDULER run as a low-privileged user account (usually nobody, see Oracle forums).
To debug this issue, can you:
run a simple script that outputs the UID
check whether this user is allowed to create / overwrite files in /app/oracle/script/
Also, I'd recommend either specifying the absolute path for your SPOOL file instead of just the file name, or using cd before your SQL/Plus call to ensure the SPOOL file is created in the correct directory.
I am trying to create a batch file for windows (XP) which will have several sqls and when its run it would
1. connect with oracle
2. set the userid/password/schema
3. run each sql in the loop and
4. output each sql outputs to its own flat file.
I have started the script
#ECHO off
SET STATE=fl
TABLE1=AGENCY
set SQL1="SELECT Column_ID||CHR(31)||column_ENTITY_CD||CHR(31) FROM AGENCY"
set TABLE2=FIRM
set SQL2="SELECT Column_ID||CHR(31)||Column_NM||CHR(31) FROM FIRM"
set TABLE3=FL_CO_LOB
Set SQL3="SELECT Column_ID||CHR(31)||Column_LOB_CODE||CHR(31) FROM FL_CO_LOB"
...
SET NumberOfTables=19
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /l %%A IN (1,1,%NumberOfTables%) DO (
echo !SQL%%A!
)
endlocal
I can get the SQL out of the variable but don't have any clue how to connect to oracle and run the sql and get the output to a defined file.
please give me some direction.
one thing to notice that the echo is printing including the double quote. but If i don't have them then it just print the 1st word not the whole query.
Thanks
If you've installed the oracle client on your workstation, you have SQLPlus.exe for command line work with the database. Your TNSNAMES.ORA file needs to be up to date, and tnsping needs to be able to locate your service.
I think you'll need to change your approach. The scripts you want to run will need to be fed to the SQLPlus.exe program, rather than being delivered semi-interactively.
I suggest creating a .sql script instead of creating evnironment variables
Your batch file line might look like:
#ECHO off
SET STATE=fl
set TABLE1=AGENCY
set TABLE2=FIRM
echo SELECT Column_ID^|^|CHR(31)^|^|column_ENTITY_CD^|^|CHR(31) FROM %TABLE1% > tablecommands.sql
echo SELECT Column_ID^|^|CHR(31)^|^|Column_NM^|^|CHR(31) FROM %TABLE2% >> tablecommands.sql
echo SELECT Column_ID^|^|CHR(31)^|^|Column_LOB_CODE^|^|CHR(31) FROM FL_CO_LOB >> tablecommands.sql
...
<until your 19 SQL statements are declared>
SQLPlus User/Password#Database #tablecommands.sql
Add the sqlplus login command before your sql commands in your batch file. It executes and writes to logs file where the batch file resides
syntax : sqlplus -s ora_user_name/ora_user_password [as sysdba]#ora_sid#"path_to_sql_file" > output.log
ex. sqlplus -s scott/tiger#xe #"D:\Oralcle\scripts\sql_file.sql" > output.txt