shell调用存储过程

最近在有个需求  就是定时查询数据库,有三个方案,
   1.java定时任务
   2.数据库定时器,定时执行存储过程
   3.shell脚本调用存储过程,crontab定时执行shell脚本

   我使用的是第三种方法,这一篇主要数一下我踩过的坑!!!

   shell脚本,调用存储过程:
   mysql -h *** -u *** -D *** -p*** -e ***

   -h ip地址
   -u 数据库用户
   -D 数据库
   -p密码
   -e 调用存储过程的语句 call haha()
   
   -p和密码之间没有空格,请注意!

   shell脚本范例:
    #ip地址
    HOST="xxx"
    #端口号
    PORT="xxx"
    #用户名
    USER="xxx"
    #密码
    PASSWORD="xxx"
    #数据库名
    DATABASE="xxx"
    #路径,日志所在路径,
    DIR="xxx"
    #日志
    log="log.txt"
    #存储过程
    CALL="call m_user_day()"
    #当前时间
    cur_dateTime="`date +%Y-%m-%d,%H:%m:%s`"


    MAILTO=""
    cd ${DIR}

    #输入到日志
    SQL="exec mysql -h${HOST} -u${USER} -p${PASSWORD} -D ${DATABASE} --default-character-set=utf8 -e \"${CALL}\""
    echo ${SQL} >> ${log} 2>&1
    echo ${cur_dateTime} >> ${log} 2>&1

    if   mysql -h ${HOST} \
           -u ${USER} \
           -p${PASSWORD} \
           -D ${DATABASE} \
           --default-character-set=utf8 \
           -e "${CALL}"; then
          echo "ok"  >> ${log} 2>&1
    else
          echo "error" >> ${log} 2>&1
    fi

    exit
    shell编写后,肯定要先测试一下shell脚本是否可以:

    一.MAILTO="",禁止发送邮件,定时器执行shell脚本时,会以发送邮件的形式表现,使shell脚本的echo无作用
      所以必须禁止发送邮件,
    二.如果在shell脚本中需要进行输出的话,echo并不会起作用,只能将语句输出到一个日志文件中,
      需要 >> 重定向到一个文件中,并在后面加上2>&1 如echo "ok"  >> ${log} 2>&1
      需要 MAILTO=""  >>  2>&1 三者配合才可以将日志输出到文件中
    三.如果脚本语句没有问题的话,进行执行脚本,脚本执行时,如果超过10秒,那你对数据库的操作就是失败的了,
    最有可能报的一个错误就是 连接不到数据库,这是一个很笼统的错误,错误原因很多
       1.网络原因,
          ping www.baidu.com  没有问题
      ping 数据库所在的服务器ip 不通,就是网络的问题了,
      我就是这样的问题,(云服务器上执行脚本,操作公司内网服务器上的数据库),执行脚本时,一直提示mysql连接失败
      所以,先ping ip,看看是否可以连通,如果不可以,就要注意一下了
    2.ping ip可以的话,在执行shell脚本,还是提示mysql连接失败,就有可能是mysql的问题了
       有可能是mysql没有开启远程调用权限
       解决办法:1.关闭mysql,在my.ini文件的最后一行加上一句话  skip-grant-tables 开启mysql
                  2.更新user表的Host为% update user authentication_String
              UPDATE user SET authentication_String=PASSWORD(’newpassword’) where USER=’root’;

              注意,mysql的password列有可能变为了authentication_String

              FLUSH PRIVILEGES重启misql

              登陆mysql

   之后就ok了

 

 

 

   

 

在java代码中调用执行shell脚本,sqlldr导数与使用sqlplus在shell调用执行存储过程。 linux环境中有2个dba的用户:oracle、erm 还有1个web用户:erm 在linux环境中,这三个用户都可以直接在任意目录下执行该shell脚本,可是在java代码中调用shell脚本时,报了如下4个错误: 1、sqlldr: command not found 2、sqlplus: command not found 3、0750: You may need to set ORACLE_HOME to your Oracle software directory 4、Message 2100 not found; No message file for product=RDBMS, facility=ULMessage 2100 not found; No message file for product=RDBMS, facility=UL$ 检查了dba用户和web用户下关于oracle的所有环境变量发现没有问题 (/home/oracle/.profile 与 /home/erm/.profile 环境变量文件为隐藏文件需使用 ls -a 命令查看) 在网上查了一遍以后有如下几种处理办法: 1、没有oracle_home目录的执行权限,无法进入到bin目录,使用chmod 755 $oracle_home更改目录权限;使用chmod 755 $oracle_home/lib更改目录权限;对目录$oracle_home/rdbms/mesg目录赋予相应权限;当需要给非oracle用户配置使用sqlldr时,不单需要配置环境变量,还需要把相关目录的访问权限赋予该用户。【采用此法测试以后还是出现上面的错误】 2、用sh直接执行shell和在java直接执行shell是有区别的,要在shell文件内增加oracle的环境变量即. /home/oracle/.bash_profile 这句话,否则在执行sqlldr会报如下异常: Message 2100 not found; No message file for product=RDBMS...... facility=UL 【采用此法测试以后继续报错,但是这个方法有引导作用,继续往下看】 因为我在linux环境下执行shell脚本时sqlldr命令和sqlplus命令是正常执行的,没有任何问题,但是在java代码中调用脚本时却报错,所有排除了其他原因,只可能是环境变量的问题, 于是我把oracle的所有环境变量直接复制到shell脚本文件中,在java中调用了一下,然后所有问题迎刃而解! 具体代码参看文件内容
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值