shell调用oracle例子

 

         数据抽取到临时表(存储过程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;

//dmuser
public 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 [[email protected]]
 * @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 [[email protected]]
 * @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 [[email protected]]
 * @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 < 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 < set heading off;
SELECT T.BATC FROM   INTFUSER.abc T WHERE  ROW
NUM = 1;
exit;
EOF`

############获取多变量#####

ftp_v=` sqlplus -s prip_user/prip_user< set heading off
SELECT T.SFTP_IP,
       T.SFTP_USER,
       T.SFTP_PASSWORD
FROM   PRIP_INTF_INFO T;
exit
EOF
`
ftp_ip=`echo $ftp_v | awk -F' ' '{print $1}'`
ftp_user=`echo $ftp_v | awk -F' ' '{print $2}'`
ftp_passwd=`echo $ftp_v | awk -F' ' '{print $3}'`

####如果使用的时候直接使用字符串

也可以将sql的语句变量拼接起来,例如使用ftp上传的时候

v_ftp=` sqlplus -s prip_user/prip_user< set heading off
SELECT
       T.SFTP_USER||','||
       T.SFTP_PASSWORD ||' sftp://'||
       T.SFTP_IP
FROM   PRIP_INTF_INFO T;
exit
EOF

`

结果:v_ftp:rbsx000100,eqsU3w sftp://10.110.41.150

 

lftp -u $v_ftp< lcd $LOCAL_PATH    --上传文件的存储位置
put $FTILE_NAME    --文件的名
bye    --结束ftp的命令
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 < 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 < 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

find /a/b/c -name '*.txt'| xargs cat| wc -l           //获取目录文件夹c下txt文件的总行数

 

xargs:获取管道的参数,以流的形式 传递给下一个参数

 

 

 

 

 

 

 

你可能感兴趣的:(linux)