shell脚本操作oracle数据库

来源:互联网 发布:php在线答题系统 编辑:程序博客网 时间:2024/06/06 00:12


         数据抽取到临时表(存储过程test(num)执行该操作),在将表中数据写入到txt文件,最后将txt打包zip

原先一直和代码打交道,做任何事都考虑的是使用代码完成,所以一开始就写了份代码:

        1:读取配置配置文件(里面写了要操作的号)excel              

             

emptyimport jxl.Cell;import jxl.Sheet;import jxl.Workbook;import java.io.File;import java.util.ArrayList;import java.util.List;//dmuserpublic class load_excl {    List lis = new ArrayList();    public List findlist(String str) {        try {            Workbook book = Workbook.getWorkbook(new File(str));            // 获得第一个工作表对象            Sheet sheet = book.getSheet(0);            // 得到第一列第一行的单元格            System.out.println("数据添加到列表begin");            for (int i = 0; i < 10; i++) {                int stat = 3;                Cell cell1 = sheet.getCell(0, i );               // Cell cell2 = sheet.getCell(3, i + 2);                String result = cell1.getContents();               // String result2 = cell2.getContents();                if (result == null || result == "" || "".equals(result)) {                    break;                }                lis.add(result);            }            System.out.println("数据添加到列表end");            book.close();        } catch (Exception e) {            System.out.println(e);        }        return lis;    }    public static void main(String[] args) {        load_excl a=new load_excl();             List abc=  a.findlist("D://batchno.xls");             for (String s : abc) {            System.out.println(s);        }    }}

         2:执行存储过程

       

import java.sql.CallableStatement;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;/** * @Author: Smile [smile_dip@163.com] * @Description: * @Date; 2017/9/9 14:54 */public class oracle125 {public  void  add(String li){    String driver = "oracle.jdbc.driver.OracleDriver";    String url = "jdbc:oracle:thin:@ip:1521:ods";    String user = "用户名";    String pwd = "密码";    Connection conn = null;    CallableStatement cs = null;    try {        Class.forName(driver);        conn = DriverManager.getConnection(url, user, pwd);        //P_119():存储过程        cs = conn.prepareCall("{ call P_119(?) }");        cs.setString(1, li);        cs.execute();    } catch (SQLException e) {        e.printStackTrace();    } catch (Exception e) {        e.printStackTrace();    } finally {        try {            if (cs != null) {                cs.close();            }            if (conn != null) {                conn.close();            }        } catch (SQLException e) {        }    }}}

         3:执行shell脚本

emptyimport ch.ethz.ssh2.ChannelCondition;import ch.ethz.ssh2.Connection;import ch.ethz.ssh2.Session;import ch.ethz.ssh2.StreamGobbler;import org.apache.commons.io.IOUtils;import java.io.IOException;import java.io.InputStream;import java.nio.charset.Charset;/** * @Author: Smile [smile_dip@163.com] * @Description: * @Date; 2017/9/9 11:52 */public class RemoteShellExecutor {    private Connection conn;      /** 远程机器IP */      private String ip;      /** 用户名 */      private String osUsername;  /** 密码 */    private String password;    private String charset = Charset.defaultCharset().toString();      private static final int TIME_OUT = 1000 * 5 * 60;    /**      * 构造函数        * @param ip        * @param usr      * @param pasword      */           public RemoteShellExecutor(String ip, String usr, String pasword) {                this.ip = ip;               this.osUsername = usr;                this.password = pasword;             }              /**      * 登录      * @return     * @throws IOException      */             private boolean login() throws IOException {                 conn = new Connection(ip);                  conn.connect();                  return conn.authenticateWithPassword(osUsername, password);             }            /**    * 执行脚本      *     * @param cmds     * @return      * @throws Exception     */              public int exec(String cmds) throws Exception {                 InputStream stdOut = null;               InputStream stdErr = null;                String outStr = "";                 String outErr = "";                 int ret = -1;                  try {                     if (login()) {                            // Open a new {@link Session} on this connection                            Session session = conn.openSession();                              // Execute a command on the remote machine.                              session.execCommand(cmds);                            stdOut = new StreamGobbler(session.getStdout());                           outStr = processStream(stdOut, charset);                             stdErr = new StreamGobbler(session.getStderr());                             outErr = processStream(stdErr, charset);                             session.waitForCondition(ChannelCondition.EXIT_STATUS, TIME_OUT);                             System.out.println("outStr=" + outStr);                             System.out.println("outErr=" + outErr);                              ret = session.getExitStatus();                        } else {                              throw new Exception("登录远程机器失败" + ip); // 自定义异常类 实现略                         }                      } finally {                         if (conn != null) {                                conn.close();                              }                         IOUtils.closeQuietly(stdOut);                         IOUtils.closeQuietly(stdErr);                     }                 return ret;            }              /**       * @param in       * @param charset        * @return      * @throws IOException       * @throws UnsupportedEncodingException       */            private String processStream(InputStream in, String charset) throws Exception {                byte[] buf = new byte[1024];               StringBuilder sb = new StringBuilder();                 while (in.read(buf) != -1) {                         sb.append(new String(buf, charset));                      }                return sb.toString();             }         }
         4:整体调用循环

import java.io.BufferedReader;import java.io.InputStreamReader;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.DriverManager;import java.util.ArrayList;import java.util.List;/** * @Author: Smile [smile_dip@163.com] * @Description: * @Date; 2017/9/9 14:15 */public class shelltest {    public static void main(String[] args) throws Exception {        //连接oracle      //  OracleConnect con=new OracleConnect();        // write your code here        //读取 oracle 中的批次号        load_excl excl =new load_excl();        oracle125 orcl125 =new oracle125();        List lis=new ArrayList();        lis=excl.findlist("D://batchno.xls");        //循环批次号        for (String li : lis) {            // 设置执行完的状态            System.out.println("当前批次号:"+li);            //连接oracle,执行存储过程            System.out.println("数据入库");            orcl125.add(li);            System.out.println("数据end");            //执行shell脚本            Thread.sleep(10*1000);            RemoteShellExecutor executor = new RemoteShellExecutor("ip", "用户名", " 密码");            // 执行myTest.sh 参数为java Know dummy            String  abc="/picclife/tools/ciitc/119.sh "+li;            System.out.println(executor.exec(abc));            System.out.println(li+"批次完成");       /*     try {                String shpath="/home/felven/word2vec/demo-classes.sh";                Process ps = Runtime.getRuntime().exec(shpath);                int exitValue= ps.waitFor();                if(0!=exitValue){                    isOK="no";                    System.err.println("call shell failed.errorcodeis:"+exitValue);                    //停止继续循环执行                    break;                }                BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));                StringBuffer sb = new StringBuffer();                String line;                while ((line = br.readLine()) != null) {                    sb.append(line).append("\n");                }                String result = sb.toString();                System.out.println(result);            }            catch (Exception e) {                e.printStackTrace();            }            */        }    }}
         

其实所有的对数据的操作不考虑空间,时间等因素都可以通过存储过程+shell脚本完成

    下面介绍使用shell+oracle存储过程结合完成需求

        oracle:游标(类似list),循环(while,for),触发器(拦截器),存储过程(类 中的main),函数(函数),判断(if)===》Java语言

                    综上所有对数据的操作都在存储过程中完成,打包写入txt等文件用shell完成

我们可能用到的场景:

1:循环执行整个脚本

2:shell脚本调用存储过程

3:shell脚本调用打包程序

4:shell脚本验证数据文件个数是否正确

5:验证表是否存在

6:shell脚本步骤写人log文件

7:如何判断存储过程是否执行正确

8:验证文件的大小是否超限

9:对shell脚本传参数

##################shell 循环 文本 数据 如果数据等于abc结束######################


while read var1
 do


if [ $var1 -eq 'abc' ]
then
   break
fi


done < batchno.txt


########################shell执行存储过程############################


sqlplus -s 用户/密码@//ip:端口/service_name <<EOF 
set echo off;
 
set serveroutput on;
 
set timing on;
 
 //test()是存储过程名
exec test(1);  
 
commit;
 
exit;
 
EOF




########################shell读取oracle中的数据存到BATC,做变量 #################

BATC=`sqlplus -s circ_user/user_circ <<EOF
set heading off;
set feedback off;
set pagesize 0;
set verify off;
set echo off;
SELECT T.BATC FROM   INTFUSER.abc T WHERE  ROW
NUM = 1;
exit;
EOF`

########################调用打包程序#######################################
####调用另一个脚本#####
./test2.sh

####打包#######

#!/bin/sh
#进入路径
cd /picclife/tools/cross
#删除要存放文件夹下的全部文件
rm -rf /picclife/tools/cross/circ/*

##########数据从oracle临时表到文件######################


/oraexpdata/sqluldr2_linux64_10204.bin 用户名/密码 query="SELECT  * FROM tablename" charset=UTF8  file="/picclife/tools/cross/F_"$BATC"_00%b.txt"   rows=
10000000 batch=yes  field=0x7c


############数据文件打包#######################


##文件名##
file="H_"$BATCHNO"_001.zip"
##要打包到#####
cd /picclife/tools/cross/bak
##########打包######################
7za a -tzip  -r  $pici /picclife/tools/cross/circ/000100




####################shell脚本压缩文件txt文件个数(文件的个数 可能会有 a_123_1.txt a_123_2.txt 文件视为1个),写入日志############


## awk -F_ 对结果的每一行数据按_分割 {print$3}:获取第三个字段 uniq:去重  wc:行数 字数 字节数 (wc写在前面+文件位置/名称,wc写在文件后面要先打开或读取文件例如more test.txt wc) awk 按空格分awk -F: '/root/' /etc/passwd  搜索/etc/passwd有root关键字的所有行  最后结果输出到log_10G.out文件




echo `unzip -v /picclife/tools/ciitc/bak/H_$BATCHNO_001.zip| grep ".txt"|awk -F_ '{print$3}'|uniq|wc|awk '{print $1}'` >>/picclife/tools/ciitc/log_10G.out


#######################验证表是否存在###################################


tab=`sqlplus -s querydep/querydeptwo <<EOF
set heading off;
set feedback off;
set pagesize 0;
set verify off;
set echo off;
select count(*) from user_tables where table_name = 'BS_BATCHNO';
exit;
EOF`
##不存在则创建表################
if [ $tab -eq 0 ]
then  
echo "NOT EXISTS"
sqlplus -s querydep/querydeptwo <<EOF
set heading off;
set feedback off;
set pagesize 0;
set verify off;
set echo off;
create table BS_BatchNo(
       BatchNo varchar2(20) not null,
       TransactionNo varchar2(24) not null
);
exit;
EOF;
fi;
#################创建表也可以创建相同的表结构,不包含数据################


create table abc AS select * from b1 where 1=0


################验证文件的大小是否超限  超过10G  或者小于0G(-size -0G),   ############################


find /picclife/tools/cross/bak/ -size +10G -exec ls -ld {} \; >>/picclife/tools/ciitc/log_10G.out




###########如何判断存储过程是否执行正确#########################################


其实存储过程是可以往表写数据的,如果存储过程报错,就插入一条错误日志进入表

在shell中查询错误数据量大于0,就终止,break 跳出循环,就能结束继续操作

#也可以 在脚本出错的时候终止脚本的执行  exit ,在循环和if都可用exit停止

[oracle@ODSDEVDB09 ~]$ more ./test1.sh

#!/bin/sh

 while read va

do

 if [ $va == 100 ]

then 

 exit

fi

echo $va

done < abc

[oracle@ODSDEVDB09 ~]$ ./test1.sh 

abc

tt

[oracle@ODSDEVDB09 ~]$ cat -n abc

     1 abc

     2 tt

     3 100

     4 abcd

     5 zxy


shell里面流程同代码中的流程,先循环读取文本需要处理的号,在找到对应的存储过程,将数据装入txt,最后打包,并校验正确性

######################对shell脚本传参数#############################

[oracle@ODSDEVDB09 ~]$ cat test2.sh

#!/bin/bash

echo "first :" $1

echo "second: " $2

[oracle@ODSDEVDB09 ~]$ ./test2.sh

first :

second: 

[oracle@ODSDEVDB09 ~]$ ./test2.sh abc 123

first : abc

second:  123

###########################shell的文本替换###################################

sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出

  sed ‘s/  / g’ file  (实际上文本木有改)    全部替换

[oracle@ODSDEVDB09 ~]$ cat abc   
bc
dd hello heolhello
hellofdhellogdayhello
zxyizxyasdwuzxaszxysqswqzxy
am ddddddddddddddddabdfea
a bb aa  cc
hello word

[oracle@ODSDEVDB09 ~]$ sed  's/hello/world/g' abc
bc
dd
world heolworld
worldfdworldgdayworld
zxyizxyasdwuzxaszxysqswqzxy
am ddddddddddddddddabdfea
a bb aa  cc
world word


[oracle@ODSDEVDB09 ~]$ cat abc
bc
dd hello heol hello
hellofdhellogdayhello
zxyizxyasdwuzxaszxysqswqzxy
am ddddddddddddddddabdfea
a bb aa  cc
hello word

#################################################

vim :s    :文本替换命令,需要使用vim 在线打开文件,在做处理

vim abc
bc
dd jjllo jjol jjllo
bc
dd jjllo jjol jjllo
hellofdhellogdayhello
ttittasdwuzxasttsqswqtt
am ddddddddddddddddabdfea
a ss aa  cc
hello word

:g/tt/s//hello/g                  //全部替换

bc

dd jjllo jjol jjllo
bc
dd jjllo jjol jjllo
hellofdhellogdayhello
helloihelloasdwuzxashellosqswqhello
am ddddddddddddddddabdfea
a ss aa  cc
hello word

: 1 ,$ s/hello/2017/g              //全部替换

bc
dd jjllo jjol jjllo
bc
dd jjllo jjol jjllo
2017fd2017gday2017
2017i2017asdwuzxas2017sqswq2017
am ddddddddddddddddabdfea
a ss aa  cc
2017 word









原创粉丝点击