某数据库有几张表更新,本地数据库增量更新数据,用脚本定时执行实现。
由于无blob/clob字段,使用sqlldr导入数据:查询目的数据库,以"|"分割导出所有数据,保存在./data/tablename.new
比较 tablename.new和tablename.old,将 tablename.new有,而tablename.old没有的数据更新至目的数据库,并添加至tablename.old
./data/tablename.ctl存放sqlldr控制文件
./log 存放相关日志
执行时发现bash中的while创建了子shell,不能保存变量的值,解决办法:
1、使用其他shell,如:ksh
2、形如 while read line ;do ... ;done < file
代码如下:
1 #!/usr/bin/ksh 2 3 DEBUG="false" 4 if [ $DEBUG = "true" ];then 5 orig_dir="." 6 else 7 cd 8 . ./.profile 9 orig_dir="${HOME}" 10 fi 11 v_date=`date +%Y%m%d%H%M%S` 12 ############################################################################### 13 # 日志文件,大于20M时压缩半数行 14 cd $orig_dir 15 log="$orig_dir/log/alpha.log" 16 [ ! -d $orig_dir/log ] && mkdir $orig_dir/log 17 [ ! -d $orig_dir/cfg ] && mkdir $orig_dir/cfg 18 [ ! -d $orig_dir/data ] && mkdir $orig_dir/data 19 if [ -e $log ];then 20 log_size=`ls -l $log | awk '{printf("%d",$5)}'` 21 if [ -n "$log_size" -a $log_size -gt 20971520 ];then 22 half_line=`awk 'END{printf("%d",NR/2)}' $log` 23 perl -ni -e "print if($.>$half_line)" $log 24 fi 25 fi 26 ############################################################################### 27 # 写日志 28 wlog() { 29 echo "`date +%Y-%m-%d' '%H:%M:%S`: $*">>$log 30 } 31 ############################################################################### 32 # 函数:get_col_type 获取列、类型 33 # 传递参数:用户名 密码 数据库名 表所有者 表名 34 get_col_type() { 35 db_user=$1 36 db_pass=$2 37 db_name=$3 38 tb_own=$4 39 tb_name=$5 40 tmp=./cfg/${tb_name}.tmp 41 tb_name="${tb_own}.${tb_name}" 42 sqlplus ${db_user}/${db_pass}@${db_name}<<EOF 43 set heading off feedback off pagesize 0 verify off echo off 44 spool $tmp 45 desc ${tb_name}; 46 spool off 47 quit 48 EOF 49 } 50 ############################################################################### 51 # 函数:make_ctl 生成控制文件 52 # 传递参数:目的表名 53 make_ctl() { 54 d_name=$1 55 ctl_file=./data/${d_name}.ctl 56 echo "load data" > $ctl_file 57 echo "infile './data/${d_name}.unl'" >> $ctl_file 58 echo "append into table ${d_name}" >> $ctl_file 59 echo "fields terminated by '|'" >> $ctl_file 60 echo "(" >> $ctl_file 61 cat ./cfg/${d_name}.ini|grep -v '^[ ]*$'|grep -v '^#'|while read column col_type 62 do 63 case $col_type in 64 NUMBER|VARCHAR|VARCHAR2) 65 echo "$column," >> $ctl_file ;; 66 DATE) 67 echo "$column "to_date(:$column,'yyyymmddhh24miss')"," >> $ctl_file ;; 68 *) 69 wlog "未识别的类型:$col_type" ;; 70 esac 71 done 72 echo ")" >> $ctl_file 73 # 替换末尾的,)为) 74 perl -pi -e 'undef $/;s/, ? )/ )/' $ctl_file 75 } 76 77 ############################################################################### 78 # 函数:select_sql 查询数据 79 # 传递参数:用户名 密码 数据库名 数据文件名 表所有者 查询语句 表名 80 # select CALL_ID||'|'||to_char(END_TIME,'yyyymmddhh24miss')||'|'||CALLER||'|'||SERVICE_NO||'|'||CALL_PURPOSE from tablename; 81 select_sql() { 82 db_user=$1 83 db_pass=$2 84 db_name=$3 85 data_file=$4 86 tb_own=$5 87 sql_line=$6 88 tb_name=$7 89 sql_line="$sql_line from ${tb_own}.${tb_name}" 90 wlog "查询sql:$sql_line" 91 # set closep '|' 92 sqlplus -S /nolog<<EOF 93 set heading off feedback off newpage none pagesize 0 echo off termout off trimout on trimspool on linesize 800 94 conn ${db_user}/${db_pass}@${db_name} 95 spool ${data_file} 96 $sql_line; 97 spool off 98 quit 99 EOF 100 } 101 102 ############################################################################### 103 # 函数:handle 处理数据 104 # 传递参数:配置文件 105 handle() { 106 table_name=$1 107 cat $table_name|grep -v '^#'|while read suser sname dname 108 do 109 # 如果dname为空,默认使用sname 110 [ -z "$dname" ] && dname=$sname 111 sname=`echo $sname | tr 'A-Z' 'a-z'` 112 dname=`echo $dname | tr 'A-Z' 'a-z'` 113 114 [ -e ./log/${dname}.log ] && : > ./log/${dname}.log 115 [ -e ./log/${dname}.bad ] && : > ./log/${dname}.bad 116 [ -e ./log/${dname}.unl ] && : > ./log/${dname}.unl 117 118 if [ ! -e ./cfg/${dname}.ini ];then 119 wlog "不存在./cfg/${dname}.ini,开始获取${dname}列配置..." 120 get_col_type dest_db_user dest_db_pass DBNAME dest_db_user $dname 121 cat ./cfg/${dname}.tmp|grep -v "^SQL>" |grep -v " Name " |grep -v " -------" | tr -d '