spool使用脚本封装

时间:2022-09-23 22:41:43

oracle的spool工具可以将数据导出为文本格式,有很强的功能和实用性,如果能灵活应用,能带来很多好处和便捷。

下面是我写的两个示例脚本,使用着可以直接拷贝使用,如有更好的改进,请补充。
在unix/linux下,vi sqlexport.sh,下面是 sqlexport.sh的文件内容:
#!/bin/sh
if [ $# -ne 3 ]; then
echo "usage:$0 user/passwd@dbstr sqlfile exportfile";
exit 1;
fi
dbstr=$1;
sqlfile=$2;
outfile=$3;
echo $dbstr;
sqlplus $dbstr<<EOF
set pages 9999
set heading off
set echo off
set feedback off

@$sqlfile

exit;
EOF
mv out.txt $outfile
编写sql模版
template.sql
下面是文件内容:
set termout off
set echo off
set feedback off
set heading off
set verify off
--pagesize 0用来去除空行
set pagesize 0
set trimspool on
spool out.txt
select 'analyze table ' || owner || '.' || table_name ||
       ' estimate statistics sample 5000 rows;'
  from dba_tables
 where owner in ('DEV');
select
 'analyze index '||owner||'.'||index_name||' compute statistics;'
 from dba_indexes
 where owner in ('DEV');
spool off
使用者可以替换template.sql里面的sql语句,就可以导出自己想要的数据了。
然后执行命令./sqlexport.sh dev/chenli@testdb tables.sql 2.txt
打开2.txt就是自己想要的参数导出数据了
脚本sqlexport.sh有三个参数,第一个参数是sqlplus登录数据库的命令串,如user/passwd@dbstr格式,第二个参数就是sql文件名,第三个参数是导出文件名,使用的时候只要按照template的样式,修改其中的查询sql语句就可以了。

 

提供另外一个例子,内容如下:

#! /usr/bin/sh

DAY=`date "+%Y%m%d"`
BILLING_CYCLE=`date "+%Y%m"`
out_file=''
dest_file=''

#第一个参数是帐期yyyymm
if [ $# -eq 1 ]
then
  BILLING_CYCLE=$1
fi

out_file="Bill_NUMBER_TO_ACCESS_NUMBER_"$BILLING_CYCLE.txt
dest_file="Bill_NUMBER_TO_ACCESS_NUMBER_"$BILLING_CYCLE


sqlplus bboss/bboss@cfcs1a<<EOF
--生成虚拟计费号到铁通号码映射表
set serverout on;
declare
  gs_ErrMsg  varchar(100);
  sql_text varchar2(2000);
  bill_month  number(8) := 0;
  field_value1 varchar2(300);
  field_value2 varchar2(300);
  str_len1  number := 0;
  str_len2  number := 0;
  i_index     number := 0;
  j_index     number := 0;
  start_value number := 0;
  end_value   number := 0;
  --从定购属性中查找155号码和铁通接入号间的关系
  cursor c1 is
                select t1.bill_id,t1.city_id, t2.feature_value value
         From group_sub t1, group_order_feature t2
         where t1.order_id = t2.order_id
           and t1.plan_id = '70000340'
           and t2.feature_id = 5002000400
           and t1.rec_status = 1
           and t2.rec_status = 1;
begin
   select to_number(to_char(sysdate,'yyyymm')) into bill_month from dual;
   begin
    --首先把以前的记录置为无效,只有当前生成的记录是有效,这样只需要一个简单sql就能实现spool抽取数据
      update crc_num_rela set rec_status=0 where rec_status=1;
      --sql_text := 'update crc_num_rela set rec_status=0 where rec_status=1';
    --execute immediate sql_text;
    exception when others then
    null;
   end;
   
    --遍历所有记录
  for rec in c1 loop
   field_value1 := rec.value;
   str_len1 := length(field_value1);
   
   --
   while str_len1 > 0
   loop
    i_index := instr(field_value1,';');
    if i_index = 0 and str_len1 > 0 then
     i_index := str_len1;
    end if;
    
    field_value2 := substr(field_value1, 1, i_index-1);
        field_value2 := trim(field_value2);
        str_len2 := length(field_value2);
       
        field_value1 := substr(field_value1, i_index+1, str_len1-i_index);
        str_len1 := length(field_value1);
       
        if str_len2 > 0 then
           j_index := instr(field_value2,'-');
          
           --dbms_output.put_line('field_value2=' || field_value2 || ',j_index=' || to_char(j_index) || ',str_len2=' || to_char(str_len2));
          
           if j_index = 0 then
              start_value := to_number(field_value2);
              end_value := to_number(field_value2);
           else
               start_value := to_number( substr(field_value2,1,j_index-1) );
               end_value := to_number( substr(field_value2,j_index+1,str_len2-j_index) );
           end if;
          
           --循环,将分解后的数据插入临时表tmp
           loop
             --dbms_output.put_line(to_char(start_value));
             --sql_text := 'insert into tmp(misdn,cnn_num) values(''' || to_char(rec.bill_id) || ''',''' || to_char(start_value) || ''')';
             --dbms_output.put_line(sql_text);
             --execute immediate sql_text;
             insert into crc_num_rela(bill_id,crc_num,city_id,bill_month,rec_status,create_date)
             values(rec.bill_id,start_value,rec.city_id,bill_month,1,sysdate);
            
             start_value := start_value + 1;
             EXIT WHEN start_value > end_value;
           end loop;
          
        end if;
       
   end loop;
     
  end loop;
  commit;
end;
/
exit;
EOF

unlink prepare.sql

cat<<EOF >>prepare.sql
set term off
set heading off
set pages 0
set feedback off
set trimout on
set trimspool on
spool $out_file
select bill_id||',' || crc_num ||',' || to_char(city_id) ||','|| to_char(bill_month) from crc_num_rela where rec_status=1;
spool off
quit;
EOF

#用spool生成文件
sqlplus bboss/bboss@cfcs1a @prepare.sql

#如果正确地生成了文件,修改名字为要求的文件名
if [  -f "$out_file" ]; then
  mv $out_file $dest_file
fi

unlink prepare.sql

#生成ftp上传脚本
unlink ftp.script
cat<<EOF >>ftp.script
open 10.70.9.29
user chenli chenli
put $dest_file
EOF

#运行ftp上传文件脚本
cat ftp.script | ftp -n

unlink ftp.script