Pages

Showing posts with label sqlplus. Show all posts
Showing posts with label sqlplus. Show all posts

Wednesday, August 22, 2018

bash and sqlplus by Example: Kill Long Running Jobs

===============================
General
===============================
Known jobs should be running for only few minutes.
However, since they are connected via DB_LINKS to several remote databases, due to networks issues connection can be stuck, and job is hanged.
The workaround - it to kill this job, and start execution again.

Following code is executed from crontab every 15 minutes, and checks for jobs which run longer than 30 minutes.

===============================
Code
===============================

less kill_long_running_jobs.sh

#!/bin/bash
. /etc/profile
. /etc/sh/orash/oracle_login.sh igt

handle_return_code() {
  ret_code=$1
  step_name=$2
  if [[ $ret_code -ne 0 ]];then
    echo $step_name Finished With Error!! Return Code $ret_code
    exit $ret_code
  fi
}

WORK_DIR=/software/oracle/oracle/scripts
LOG_DIR=${WORK_DIR}
RUN_TIME=`date +"%Y%m%d_%H%M%S"`
LOG_FILE=killed_sessions.log
TEMP_FILE=long_running_sessions.tmp

cd ${WORK_DIR}
touch ${LOG_DIR}/${LOG_FILE}
rm -f ${TEMP_FILE}

sqlplus -s /nolog <<EOF
whenever sqlerror exit SQL.SQLCODE
@./kill_long_running_jobs.sql
EOF
handle_return_code $? ./kill_long_running_jobs.sql

if [[ ! -f ${TEMP_FILE} || ! -s ${TEMP_FILE} ]]; then
  echo "$RUN_TIME   No Long Running Sessions Found" >> ${LOG_DIR}/${LOG_FILE}
  exit 0
fi

echo reading file ${TEMP_FILE}

while read line
do
  KILL_CMD=`echo $line | awk 'BEGIN {FS="~"}{print $1}'`
  WHAT=`echo $line | awk 'BEGIN {FS="~"}{print $2}'`

  echo "$RUN_TIME   ${KILL_CMD} ${WHAT}" >> ${LOG_DIR}/${LOG_FILE}
  ${KILL_CMD}

done < ${TEMP_FILE}

less kill_long_running_jobs.sql

@./set_user.sql
connect &&user/&&pass@&&conn_str
PROMPT CONNECTED TO &&user/&&pass@&&conn_str

SET HEADING OFF
SET PAGESIZE 0
SET LINESIZE 200
SET NEWPAGE NONE
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL long_running_sessions.tmp

SELECT 'kill -9 '||V_PROCESS.spid||'~'||DBA_JOBS.what AS LINUX_KILL
FROM   V$SESSION V_SESSION,
       V$PROCESS V_PROCESS,
       DBA_JOBS_RUNNING STUCK_JOBS,
       DBA_JOBS
WHERE  V_PROCESS.addr = V_SESSION.paddr
  AND  V_SESSION.type != 'BACKGROUND'
  AND  V_SESSION.sid = STUCK_JOBS.sid
  AND  DBA_JOBS.job = STUCK_JOBS.job
  AND  logon_time < (SYSDATE - 30/1440)
  AND  UPPER(DBA_JOBS.what) IN ('EXT_MOCO.SCHEDULE;','EXT_OVMD.SCHEDULE;','EXT_IPN.SCHEDULE;','EXT_GLR.SCHEDULE;','EXT_SPARX.SCH
EDULE;')
UNION ALL
SELECT 'kill -9 4545~EXT_SPARX.SCHEDULE;' AS LINUX_KILL
FROM DUAL
WHERE 1=2;

SPOOL OFF

less set_user.sql

DEFINE user=user_name
DEFINE pass=user_pass
DEFINE conn_str=orainst

Thursday, July 19, 2018

if condition in sqlplus by Example

=================================
General
=================================
sqlplus is a non procedural language.
Thus implementing "if" condition in sql script is not straight forward.
This example, is using logic to determine weather the installation is running on EE or SE Oracle Edition, and per returned result, installing tables in Partitioned, or non Partitioned mode, or, in case table was already installed, skip the installation all together.

This is done via spooling a name of the file to be executed into generated gen_install_rep_online.sql file

Then executing the gen_install_rep_online.sql file.
=================================
Code Example, "if in sqlplus"
=================================
@../set_connection.sql
connect &&user/&&pass@&&connectstr

set serverout on
exec dbms_output.enable(100000); 
set heading off linesize 132 pagesize 1000  heading off feedback off

spool gen_install_rep_online.sql

DECLARE
  v_install_type     NUMBER;
  v_install_type_str VARCHAR2(100);
BEGIN  
  SELECT TO_CHAR(is_installed||is_ee) AS install_type 
   INTO v_install_type 
   FROM
  (
  SELECT (SELECT COUNT(*) FROM USER_TABLES WHERE table_name = 'REP_DAILY_DATA') AS is_installed,
         (SELECT COUNT(*) FROM V$VERSION WHERE UPPER(banner) LIKE '%ENTERPRISE EDITION%') as is_ee
  FROM DUAL
  );

  IF v_install_type = '01' THEN
    dbms_output.put_line('@./install_partitioned_rep_online.sql');
  ELSIF v_install_type = '00' THEN    dbms_output.put_line('@./install_non_partitioned_rep_online.sql');  
  ELSE
    dbms_output.put_line('@./do_nothing.sql');  
  END IF;
END;
/

spool off  

set heading on serverout off verify on define on
@../set_connection.sql
@./gen_install_rep_online.sql

Sunday, April 29, 2018

PL/SQ and sqlplus batch by example. Delete from Table in Three Steps

=======================
General
=======================
Generic delete from  a table using Business Logic.
Several million of records are being deleted.
The flow is a three steps process:


Step1.
pre_run_steps.sh
This create backup table for SOURCE_DATA_SUBSCRIBER (SOURCE_DATA_SUBSCRIBER_BAK) 
Creates additional temporary tables which are to be used during actual delete step.


Step2.
main_delete.sh 
The actual DELETE. 
Create the PL/SQL Package, which handles the business logic.
Call the PL/SQL package.
Progress is logged into SGA_W_LOG Table.

Step3.

post_run_steps.sh
This drop the SOURCE_DATA_SUBSCRIBER_BAK and drop additional temporary tables created in pre_run_steps.sh

=======================
Code
=======================
Step 0.
set_vipuser.sql

Step1.
pre_run_steps.sh
pre_run_steps.batpre_run_steps.sql


Step2.
main_delete.shmain_delete.bat
main_delete.sql
MULTI_DELETE.sql

Step3.
post_run_steps.shpost_run_steps.batpost_run_steps.sql

Step 0.
set_vipuser.sql
--Set the connection detailsdefine vipuser=my_userdefine vippass=my_passdefine connectStr=MY_INSTANCE
Step 1.
pre_run_steps.sh
sqlplus /nolog @pre_run_steps.sql

pre_run_steps.bat
sqlplus /nolog @pre_run_steps.sql

pre_run_steps.sql
@../set_vipuser.sql

SET SERVEROUT ON
SET HEADING OFF
SET LINESIZE 400
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF

PROMPT conn &&vipuser/&&vippass@&&connectStr
conn &&vipuser/&&vippass@&&connectStr

EXEC DBMS_OUTPUT.ENABLE(100000);

PROMPT CREATE TABLE SOURCE_DATA_SUBSCRIBER_BAK AS SELECT * FROM SOURCE_USER.SOURCE_DATA_SUBSCRIBER WHERE 1=2;
DECLARE
  v_sql_str    VARCHAR2(2000);
  v_counter    NUMBER;
BEGIN
  SELECT COUNT(*) INTO v_counter FROM USER_TABLES WHERE table_name = 'SOURCE_DATA_SUBSCRIBER_BAK'; 
  IF v_counter = 0 THEN
    v_sql_str := 'CREATE TABLE SOURCE_DATA_SUBSCRIBER_BAK AS SELECT * FROM SOURCE_USER.SOURCE_DATA_SUBSCRIBER WHERE 1=2';
  ELSE
    v_sql_str := 'TRUNCATE TABLE SOURCE_DATA_SUBSCRIBER_BAK';
  END IF;
  EXECUTE IMMEDIATE v_sql_str;
END;
/

PROMPT ALTER TABLE SOURCE_DATA_SUBSCRIBER_BAK MOVE TABLESPACE IGT_TEMP_TABLE;
ALTER TABLE SOURCE_DATA_SUBSCRIBER_BAK MOVE TABLESPACE IGT_TEMP_TABLE;

PROMPT INSERT /*+ APPEND */ INTO SOURCE_DATA_SUBSCRIBER_BAK SELECT * FROM SOURCE_USER.SOURCE_DATA_SUBSCRIBER;
INSERT /*+ APPEND */ INTO SOURCE_DATA_SUBSCRIBER_BAK SELECT * FROM SOURCE_USER.SOURCE_DATA_SUBSCRIBER;
COMMIT;

PROMPT CREATE TABLE   SGA_LOC_GRP_OUTBACK_NETWORKS
DECLARE
  v_sql_str    VARCHAR2(2000);
  v_counter    NUMBER;
BEGIN
  SELECT COUNT(*) INTO v_counter FROM USER_TABLES WHERE table_name = 'SGA_LOC_GRP_OUTBACK_NETWORKS'; 
  IF v_counter = 0 THEN
    v_sql_str := 'CREATE TABLE   SGA_LOC_GRP_OUTBACK_NETWORKS (network_id        NUMBER(10) ) TABLESPACE IGT_TEMP_TABLE;';
  ELSE
    v_sql_str := 'TRUNCATE TABLE SGA_LOC_GRP_OUTBACK_NETWORKS';
  END IF;
  EXECUTE IMMEDIATE v_sql_str;
END;
/


PROMPT CREATE TABLE   MSISDN_PROFILE_NOT_PRE
DECLARE
  v_sql_str    VARCHAR2(2000);
  v_counter    NUMBER;
BEGIN
  SELECT COUNT(*) INTO v_counter FROM USER_TABLES WHERE table_name = 'MSISDN_PROFILE_NOT_PRE'; 
  IF v_counter = 0 THEN
    v_sql_str := 'CREATE TABLE   MSISDN_PROFILE_NOT_PRE (msisdn VARCHAR2(30) NOT NULL) TABLESPACE IGT_TEMP_TABLE;';
  ELSE
    v_sql_str := 'TRUNCATE TABLE MSISDN_PROFILE_NOT_PRE';
  END IF;
  EXECUTE IMMEDIATE v_sql_str;
END;
/

PROMPT INSERT /*+ APPEND */ INTO SGA_LOC_GRP_OUTBACK_NETWORKS
INSERT /*+ APPEND */ INTO SGA_LOC_GRP_OUTBACK_NETWORKS
SELECT DISTINCT network_id 
    FROM SOURCE_USER.SGA_LOCATION_GROUP_ENTRIES 
   WHERE location_group_id IN 
         (SELECT location_group_id 
    FROM SOURCE_USER.SGA_LOCATION_GROUPS 
WHERE LOCATION_GROUP_NAME='Outback');
commit;

PROMPT INSERT /*+ APPEND */ INTO MSISDN_PROFILE_NOT_PRE(msisdn)
INSERT /*+ APPEND */ INTO MSISDN_PROFILE_NOT_PRE(msisdn)
SELECT KEY1 FROM SOURCE_USER.SFI_CUSTOMER_PROFILE WHERE ATTR1 NOT IN ('RogEngPre','RogFrPre','FidoEngPre','FidoFrPre');
commit;


PROMPT CREATE INDEX SFI_CST_PROF_IX
DECLARE
  v_sql_str    VARCHAR2(2000);
  v_counter    NUMBER;
BEGIN
  SELECT COUNT(*) INTO v_counter FROM USER_INDEXES WHERE index_name = 'SFI_CST_PROF_IX'; 
  IF v_counter > 0 THEN
    v_sql_str := 'DROP INDEX SFI_CST_PROF_IX';
  END IF;
  EXECUTE IMMEDIATE v_sql_str;
END;
/

PROMPT CREATE INDEX SFI_CST_PROF_IX ON MSISDN_PROFILE_NOT_PRE(msisdn) TABLESPACE IGT_TEMP_INDEX;
CREATE INDEX SFI_CST_PROF_IX ON MSISDN_PROFILE_NOT_PRE(msisdn) TABLESPACE IGT_TEMP_INDEX;

BEGIN
  DBMS_STATS.gather_table_stats('&&vipuser','MSISDN_PROFILE_NOT_PRE');
END;
/

PROMPT Finished Pre Run step
EXIT;



Step 2.
main_delete.sh
sqlplus /nolog @main_delete.sql

main_delete.bat
sqlplus /nolog @main_delete.sql

main_delete.sql
@../set_vipuser.sql

SET SERVEROUT ON
SET HEADING OFF
SET LINESIZE 400
SET PAGESIZE 0
SET FEEDBACK OFF

PROMPT conn &&vipuser/&&vippass@&&connectStr
conn &&vipuser/&&vippass@&&connectStr

EXEC DBMS_OUTPUT.ENABLE(100000);

PROMPT CREATE PROCEDURE MULTI_DELETE
@MULTI_DELETE.sql

PROMPT EXECUTE PROCEDURE MULTI_DELETE
PROMPT .............................
PROMPT Running DELETE....
PROMPT Follow Up on process Progress by: SELECT * FROM SGA_W_LOG ORDER BY TS_LAST_MODIFIED;
PROMPT .............................

BEGIN
  MULTI_DELETE;
END;
/

PROMPT Finished Run step  
EXIT;


MULTI_DELETE.sql
CREATE OR REPLACE PROCEDURE MULTI_DELETE IS

    v_effected_rows NUMBER;
    v_delete_rows NUMBER;
    v_row_counter NUMBER;
    v_table_name VARCHAR2(30);
    v_sql_str VARCHAR2(1000);
    v_module_name VARCHAR2(30);
    v_msg_text VARCHAR2(1000);

  BEGIN
    v_table_name :='SOURCE_DATA_SUBSCRIBER';
    v_effected_rows := 1;
    v_row_counter := 0;
    v_module_name := 'MULTI DELETE';

    v_sql_str := 'DELETE FROM SOURCE_DATA_SUBSCRIBER WHERE current_network_id NOT IN ( SELECT network_id FROM SGA_LOC_GRP_OUTBACK_NETWORKS ) AND msisdn IN( SELECT msisdn FROM MSISDN_PROFILE_NOT_PRE) AND ROWNUM < 100001';
    v_msg_text  := 'Running SQL: '||v_sql_str;

    INSERT INTO SGA_W_LOG (  procedure_name,  data,  ts_last_modified)
    VALUES(v_module_name,v_msg_text, SYSDATE);
    COMMIT;

    v_msg_text  := 'Starting at: '||TO_CHAR(SYSDATE,'YYYYMMDD hh24:mi:ss');
    INSERT INTO SGA_W_LOG (  procedure_name,  data,  ts_last_modified)
    VALUES(v_module_name,v_msg_text, SYSDATE);
    COMMIT;


    WHILE v_effected_rows > 0 LOOP

      DELETE FROM SOURCE_DATA_SUBSCRIBER
       WHERE current_network_id NOT IN ( SELECT network_id FROM SGA_LOC_GRP_OUTBACK_NETWORKS )
         AND msisdn IN( SELECT msisdn FROM MSISDN_PROFILE_NOT_PRE)
         AND ROWNUM < 100001;


      v_effected_rows := SQL%ROWCOUNT;
      v_row_counter := v_row_counter + v_effected_rows;
      COMMIT;
      
      v_msg_text := v_row_counter||' rows deleted from table '||v_table_name;      
      INSERT INTO SGA_W_LOG (  procedure_name,  data,  ts_last_modified)
      VALUES(v_module_name,v_msg_text, SYSDATE);
      COMMIT;
      
    END LOOP;
    
    COMMIT;
    
    v_msg_text := 'MANUAL_DELETE FROM '||v_table_name||' Finished Successfully';
    INSERT INTO SGA_W_LOG (  procedure_name,  data,  ts_last_modified)
    VALUES(v_module_name,v_msg_text, SYSDATE);
    COMMIT;


  EXCEPTION

    WHEN OTHERS THEN
      v_msg_text := 'Error in procedure '||v_module_name||'. Error Details: '|| SUBSTR(SQLERRM, 1, 900);
      INSERT INTO SGA_W_LOG (  procedure_name,  data,  ts_last_modified)
      VALUES(v_module_name,v_msg_text, SYSDATE);
      COMMIT;
  END MULTI_DELETE;
/


Step 3.
post_run_steps.shsqlplus /nolog @post_run_steps.sql
post_run_steps.bat
sqlplus /nolog @post_run_steps.sql

post_run_steps.sql
@../set_vipuser.sqlSET SERVEROUT ON
SET HEADING OFF
SET LINESIZE 400
SET PAGESIZE 0
SET FEEDBACK OFF
PROMPT conn &&vipuser/&&vippass@&&connectStr
conn &&vipuser/&&vippass@&&connectStr

EXEC DBMS_OUTPUT.ENABLE(100000);
PROMPT DROP TABLE 
SOURCE_DATA_SUBSCRIBER_BAK
DROP TABLE 
SOURCE_DATA_SUBSCRIBER_BAK;
PROMPT DROP TABLE SGA_LOC_GRP_OUTBACK_NETWORKS
DROP TABLE SGA_LOC_GRP_OUTBACK_NETWORKS;
PROMPT DROP TABLE MSISDN_PROFILE_NOT_PRE
DROP TABLE MSISDN_PROFILE_NOT_PRE;
PROMPT Finished Post Run step
EXIT;

Monday, July 17, 2017

Code Example: batch, sqlplus

=========================
General
=========================
Code example
Overall - read data from Database
Generate files using oracle UTL_FILE
FTP files from oracle server to customer serer
Update records in Database

The main is main_send_files.bat

=========================
Code
=========================

=======================================
main_send_files.bat
=======================================

REM set Paths
SET HOME_DIR=D:\CUST_APU_Reports\Files
SET OLD_DIR=D:\CUST_APU_Reports\OldFiles

REM Delete old temp file
IF EXIST DELnewCMD.ini DEL DELnewCMD.ini
IF EXIST del_files.txt DEL del_files.txt
IF EXIST sftp_output.log DEL sftp_output.log 

REM get date
for /f "tokens=2,3,4 delims=/ " %%i in ('date/t') do (set mm=%%i) & (set dd=%%j) & (set yyyy=%%k)
set RUN_DATE=%yyyy%%mm%%dd%

REM Override default Time
REM SET RUN_DATE='20170714'

echo %RUN_DATE% >> cust_log.txt

for /f "tokens=1,2 delims=: " %%i in ('time /t') do (set hh=%%i) & (set mm=%%j)
REM get time
set RUN_TIME=%hh%:%mm%
echo %RUN_TIME% >> cust_log.txt

echo #### >> cust_log.txt
echo Activate database package >> cust_log.txt
echo #### >> cust_log.txt
sqlplus user/pass@oraint @activate_report_new.sql %RUN_DATE%
IF NOT ERRORLEVEL 0 goto :ERROR_DB

:BRING_THE_FILES
echo before FTP >> cust_log.txt
CALL SFTPCMD2 > sftp_output.log 
type sftp_output.log >> cust_log.txt
echo Finished FTP successfully >> cust_log.txt

dir /B D:\cust_APU_Reports\Files\output*.csv /O:d >> del_files.txt
echo cd /software/oracle/admin/igt/utl_file >> DELNEWCMD.ini
for /F %%i in (del_files.txt) do (@echo rm %%i) >> delnewcmd.ini
echo bye >> DELnewCMD.ini
CALL SFTPCMD3 > sftp_output.log 
type sftp_output.log >> cust_log.txt
if NOT ERRORLEVEL 0 GOTO :ERROR_DELETING

echo send the files by sftp to the customer (10.92.40.20)>> cust_log.txt
CALL SFTPCMD SFTPCMD.ini > sftp_output.log 
type sftp_output.log >> cust_log.txt

REM echo send the files by sftp to the customer >> cust_log.txt
REM CALL SFTPCMD4 SFTPCMD4.ini > sftp_output.log 
REM type sftp_output.log >> cust_log.txt

IF NOT ERRORLEVEL 0 GOTO :ERROR_SFTP
echo Rename the sent CSV files to old directory >> cust_log.txt
for /F  %%i in (del_files.txt) do (move %HOME_DIR%\%%i %OLD_DIR%\%%i)
IF NOT ERRORLEVEL 0 GOTO :ERROR_RENAME
echo process finish succefully >> cust_log.txt
goto FINISH
:ERROR_DB
 echo Error in the DAILY_REPORTS package. >> cust_log.txt
REM REM send mail
:ERROR_DELETING
 echo Errors deleting from the cgw! >> cust_log.txt
REM REM send mail
 goto FINISH
:ERROR_SFTP
 echo Errors SFTP the files to CUST >> cust_log.txt
REM REM send mail
 goto FINISH
:ERROR_RENAME
 echo Error moving the files to the oldDir directory >> cust_log.txt
REM send mail
 goto FINISH
:FINISH

=======================================
SFTPCMD.bat
=======================================
sftp -b SFTPCMD.ini user@10.10.10.10

SFTPCMD.ini
lcd D:\CUST_APU_Reports\Files
cd ../VHE
mput CUST_APU*.csv
bye

=======================================
SFTPCMD2.bat
=======================================
sftp -b DWHNEWCMD.ini user@20.20.20.20

dwhnewcmd.ini
lcd D:\CUST_APU_Reports\Files
cd /software/oracle/admin/igt/utl_file
mget output*.csv
bye


=======================================
SFTPCMD3.bat
=======================================
sftp -b DELnewCMD.ini user@30.30.30.30


DELNEWCMD.ini
cd /software/oracle/admin/igt/utl_file 
rm CUST_APU_BHCA_20170716.csv
rm CUST_APU_BHSM_20170716.csv
bye  

=======================================
activate_report_new.sql
=======================================
exec DAILY_REPORTS.CUST_MAIN(&1);
exit;