数据库perl脚本:创建SDB各表,并导入数据

数据库perl脚本实战:创建各表,并导入数据

#!/usr/bin/perl
#/*****************************************************************************************
#/*****************************************************************************************
use strict;     # Declare using Perl strict syntax
use warnings;

默认脚本解释器位置:/usr/bin/perl
检查系统环境变量

# ------------ Variable Section ------------
my ${AUTO_HOME} = $ENV{"AUTO_HOME"};
my ${DBSERVER} = $ENV{"SDB_SERVICE_NAME"};
if ( !defined(${DBSERVER}) ) {
    print "DBSERVER is not defined";
    exit(1);
}
my ${USER} = $ENV{"SDB_USER"};
if ( !defined(${USER}) ) {
    print "USER is not defined";
    exit(1);
}
my ${PASSWD} = $ENV{"SDB_PASSWD"};
if ( !defined(${PASSWD}) ) {
    print "PASSWD is not defined";
    exit(1);
}

定义各变量并引用环境变量,defined判断变量是否为空,如果!defined成立说明变量为空,然后打印错误信息并退出,错误代码1.非正常退出。

my ${CONTROL_NAME} = substr($ARGV[0],-12);
my ${DATE} = substr(${CONTROL_NAME},0,8);
#源系统、源表名,用于拼接构目标表名及控制文件名 
my $Org_System = "aw";
my $Org_Table  = "S_INFO";
my $Table_Date = substr(${DATE},4,4);
my $TABLE_NAME_MMDD = $Org_Table."_".$Table_Date;

if ( !defined(${AUTO_HOME}) ) {
    ${AUTO_HOME} = "/home/oracle/std";
}

my ${SDB} = $ENV{"AUTO_SDB"};
if ( !defined(${SDB}) ) {
    ${SDB} = "SDB";
}

my ${ODB} = $ENV{"AUTO_ODB"};
if ( !defined(${ODB}) ) {
    ${ODB} = "ODB";
}

my ${CDB} = $ENV{"AUTO_CDB"};
if ( !defined(${CDB}) ) {
    ${CDB} = "CDB";
}

my ${MDB} = $ENV{"AUTO_MDB"};
if ( !defined(${MDB}) ) {
    ${MDB} = "MDB";
}

my ${SDBDDL} = $ENV{"AUTO_SDBDDL"};
if ( !defined(${SDBDDL}) ) {
    ${SDBDDL} = "SDDL";
}

my ${ILL_DATE} = "0001-01-02";
my ${NULL_DATE} = "0001-01-01";
my ${MAX_DATE} = "3000-12-31";

my ${LOGON_FILE} = "${AUTO_HOME}/etc/LOGON_LOAD";
my ${LOGON_STR};
my ${CONTROL_FILE};
my ${TX_DATE};
my ${TX_DATE_YYYYMMDD};
my ${TX_MON_DAY_MMDD};

$ARGV里面存放的是从外部传进来的参数,substr($ARGV[0],-12):取外部传参后12位字符定义control_name变量,再在control_name中取前8位定义为date变量;取自定义变量与date变量后4位拼接合并为月日表名变量。
定义AUTO_HOME,SDB,ODB,CDB,SDB,SDBDDL等引用环境变量,如变量为空则重新定义。

变量设置完成 ,开始编写SQLPLUS子程序块的脚本内容

# ------------ sqlplus function ------------
sub run_sqlplus_command
{
  my $rc = open(sqlplus, "| sqlplus /nolog"); #进入sqlplus环境,nolog参数表示不登录
#————————————————————————————————————————————————————————————————————————————————
#用open函数也可像命令行一样,打开和使用管道.
#       语法为:
#               open(MYVAR, "mode");
#       mode有如下两种模式:
#               "|command"        表示对MYVAR的输出相当于对command的输入.
#				如果以管道符号开头,”open” 启动一个新的命令,打开一个可写文件句柄通向
#				这个命令。你可以向这个句柄中写入内容,而你所写的将出现在这个命令的标准
#				输出里。
#               "command|"        表示command的输出作为对MYVAR的输入.
#				如果末尾的字符是一个管道时,你启动一个新的命令,打开一个通向这个命令的
#				可读文件句柄。这使得这个命令写入标准输出的内容可以在你的句柄中读到的。
#————————————————————————————————————————————————————————————————————————————————
  unless ($rc) {
      print "Could not invoke sqlplus command\n";
      return -1;
  }
 #my $rc = open(sqlplus, "| sqlplus /nolog")||die "Could not invoke sqlplus command\n";
   
# ------ sqlplus scripts ----------
  print sqlplus <<ENDOFINPUT;

conn $USER/$PASSWD\@${DBSERVER}; #连接数据库,用户/密码@数据库名
set echo on #设置运行命令是是否显示语句
set timing on  #设置显示“已用时间:XXXX”

alter session force parallel query parallel 8;
alter session force parallel dml parallel 8;
alter session force parallel ddl parallel 8;
#设置oracle查询、DML、DDL语句并行度为8;

--建表SDB技术缓冲层
WHENEVER SQLERROR CONTINUE;
DROP TABLE SDB.S01_LSB_$Table_Date;
commit;

WHENEVER SQLERROR EXIT SQL.SQLCODE;
CREATE TABLE  SDB.S01_LSB_$Table_Date (
			 ACTNO NUMBER(4) 
  ,OPNAME VARCHAR(10) 
  ,PASSWD VARCHAR(6)  
  ,CASH NUMBER(10,2)  
  ,OPDATE DATE  
  ,OPADDR VARCHAR(30)    					 
  )
TABLESPACE  tbs_SDB COMPRESS 
STORAGE(FLASH_CACHE DEFAULT)
NOLOGGING;
commit;
#建表SDB技术缓冲层
WHENEVER SQLERROR EXIT SQL.SQLCODE;
GRANT SELECT ON ${SDB}.S01_LSB_$Table_Date TO ODB;
commit;

GRANT SELECT ON ${SDB}.S01_LSB_$Table_Date TO CDB;
commit;

GRANT SELECT ON ${SDB}.S01_LSB_$Table_Date TO MDB;
commit;
#给数据贴源层、共性加工层、应用集市层用户提供SDB表的查询权限!
ENDOFINPUT
#向SQLPLUS句柄输入内容完成 
  close(sqlplus);
#关闭sqlplus句柄
  my $RET_CODE = $? >> 8;
#$?为上次执行命令:成功=0失败=1;定义变量$RET_CODE为上次命令执行结果检测值;
  if ( $RET_CODE == 0 ) {
      return 0;
  }
  else {
      return 1;
  }
#执行成功返回0,失败返回1.
}

print sqlplus <<ENDOFINPUT;
ENDOFINPUT ——从print语句到ENDOFINPUT之间的文本输出到SQLPLUS句柄,即向句柄SQLPLUS写入 ENDOFINPUT括起来的字符串作为命令行输出;

【引用】WHENEVER语句是SQL预编译程序的指示语句,而不是可执行语句。它通知预编译程序在每条可执行嵌入式SQL语句之后自动生成错误处理程序,并指定了错误处理操作。
①:WHENEVER SQLERROR action:表示一旦sql语句执行时遇到错误信息,则执行action,action中包含了处理错误的代码(SQLCODE<0)。
②:WHENEVER SQLWARNING action:表示一旦sql语句执行时遇到警告信息,则执行aciton,即action中包含了处理警报的代码(SQLCODE=1)。
③:WHENEVER NOT FOUND action:表示一旦sql语句执行时没有找到相应的元组,则执行action,即 action包含了处理没有查到内容的代码(SQLCODE=100)。

针对上述三种异常处理,用户可以指定预编译程序采取以下三种行为(action):
Ⅰ:WHENEVER …GOTO:通知预编译程序产生一条转移语句。
Ⅱ:WHENEVER…CONTINUE/EXIT:通知预编译程序让程序的控制流转入到下一个主语言语句或退出。
Ⅲ:WHENEVER…CALL:通知预编译程序调用函数。
其完整语法如下:WHENEVER {SQLWARNING | SQLERROR | NOT FOUND} {CONTINUE | GOTO stmt_label | CALL function()}

主程序块:

# ------------ main function ------------
sub main
{
   my $ret;
   my $localtm=localtime(time());
   print "\nbatch exec STARTTIME:$localtm\n\n";#批处理执行开始时间
	
   # Call sqlplus command to load data
   $ret = run_sqlplus_command();

   my $localtm=localtime(time());
   print "\nbatch exec ENDTIME:$localtm\n\n";#批处理执行结束 时间
   
   my $sqlldr_ret = EDW::run_sqlldr_command($Org_System,$Org_Table,$DATE,"1");
   print "run_sqlplus_command() = $ret\n\n";
   print "run_sqlldr_command() = $sqlldr_ret\n\n";
   
   if ( $ret == 0 && $sqlldr_ret == 0 ) {
   return 0;
 }
 else {
 	 return 1;
 	}
}

调用子程序run_sqlplus_command建表
调用包模块的run_sqlldr_command方法并带入参数Org_System,Org_Table,DATE,“1”,执行sqlldr批量导入!
打印执行结果,如果建表和导入同时成功则返回0,否则返回1.

程序块

# ------------ program section ------------
if ( $#ARGV < 0 ) {
   print "Usage: [perl program Control_File] (Control_File format: dir.jobnameYYYYMMDD or sysname_jobname_YYYYMMDD.dir) \n";
   print "\n";
   exit(1);
}
#判断无输入参数报错退出
# Get the first argument
${CONTROL_FILE} = ${DATE};

if (${CONTROL_FILE} =~/[0-9]{8}($|\.)/) {
   ${TX_DATE_YYYYMMDD} = substr($&,0,8);#在模式匹配后调用重用部分的结果可用变量$n,全部的结果用变量$&
}
else{
   print "Usage: [perl program Control_File] (Control_File format: dir.jobnameYYYYMMDD or sysname_jobname_YYYYMMDD.dir) \n";
   print "\n";
   exit(1);
}
#CONTROL_FILE引用之前的DATE进行匹配 ,如参数输入格式不对,正则匹配不成功报错退出。匹配成功后的8位日期截取出来作为TX_DATE_YYYYMMDD的内容。
${TX_MON_DAY_MMDD} = substr(${TX_DATE_YYYYMMDD}, length(${TX_DATE_YYYYMMDD})-4,4);
${TX_DATE} = substr(${TX_DATE_YYYYMMDD}, 0, 4)."-".substr(${TX_DATE_YYYYMMDD}, 4, 2)."-".substr(${TX_DATE_YYYYMMDD}, 6, 2);
open(STDERR, ">&STDOUT");
#输出错误信息
my $ret = main();
exit($ret);

运行主程序main;
退出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值