命令行执行 Oracle 存储过程并导出查询结果

1. 需求

        写个脚本,每月 1 号 9 点执行,调用存储过程 s1.p1,前两个参数是(5000,5000),第三个参数是下个月的最后一天,用出参 R_BATCHNO 执行查询 select cardno from s1.t1 where batchno = ?,把这个查询的结果数据用 excle 文件方式保存,然后发送邮件。

2. 实现脚本

        monthly_card_generation.sh

#!/bin/bash

# 设置环境变量
ORACLE_BASE=/home/oracle/app/oracle; export ORACLE_BASE
ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1; export ORACLE_HOME
ORACLE_TERM=xterm; export ORACLE_TERM
PATH=/usr/sbin:$PATH; export PATH
PATH=$ORACLE_HOME/bin:$PATH; export PATH

LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib:/usr/lib64:/lib64; export LD_LIBRARY_PATH
CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib; export CLASSPATH

cd /home/oracle/dbbat;

NOW=$(/bin/date  +%Y-%m-%d)

# 数据库连接信息
DB_USER="user1"
DB_PASS="123456"

# 日志文件路径
LOG_DIR="/home/oracle/dbbat"
LOG_FILE="$LOG_DIR/monthly_card_generation.log"

# 输出文件目录
OUTPUT_DIR="/home/oracle/dbbat"
OUTPUT_FILE="$OUTPUT_DIR/monthly_card_generation.csv"

# 创建目录(如果不存在)
# mkdir -p $LOG_DIR
# mkdir -p $OUTPUT_DIR

# 日志函数
log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}

# 检查是否是每月1号
#if [ "$(date +'%d')" != "01" ]; then
#    log "Today is not the 1st of month. Exiting."
#    exit 0
#fi

log "Starting monthly card generation process..."

# 计算下个月最后一天
NEXT_MONTH_LAST_DAY=$(date -d "$(date +%Y-%m-01) +1 month -1 day" +%Y-%m-%d)
log "Next month last day: $NEXT_MONTH_LAST_DAY"

# 调用存储过程并获取批次号
BATCHNO=$(sqlplus -S ${DB_USER}/${DB_PASS} < 5000,
    p_amount => 5000,
    p_expire => TO_DATE('${NEXT_MONTH_LAST_DAY}', 'YYYY-MM-DD'),
    r_code => :v_code,
    r_batchno => :v_batchno
  );
  DBMS_OUTPUT.PUT_LINE('BATCHNO_START:' || :v_batchno || ':BATCHNO_END');
END;
/

EXIT;
EOF
)

# 检查是否获取到批次号
if [ -z "$BATCHNO" ]; then
    log "Error: Failed to generate cards or get batch number."
    exit 1
fi

log "Successfully generated cards with batch number: $BATCHNO"

# 查询cardno并导出到CSV文件
log "Exporting card numbers to $OUTPUT_FILE..."
sqlplus -S ${DB_USER}/${DB_PASS} < $OUTPUT_FILE
SET COLSEP ','
SET PAGESIZE 0
SET FEEDBACK OFF
SET HEADING ON
SET LINESIZE 1000
SET TRIMSPOOL ON
SET TERMOUT OFF
SET ECHO OFF
SET VERIFY OFF
SET UNDERLINE OFF

-- 查询数据
SELECT 'CardNumber' FROM dual;
SELECT cardno FROM s1.t1 WHERE batchno = '$BATCHNO';

EXIT;
EOF

# 检查文件是否生成成功
if [ -s "$OUTPUT_FILE" ]; then
    log "Successfully exported card numbers to $OUTPUT_FILE"
else
    log "Error: Failed to export card numbers"
    exit 1
fi

# 后处理:移除可能存在的空行和SQL*Plus版本信息
sed -i '/^$/d' $OUTPUT_FILE
sed -i '/^Disconnected/d' $OUTPUT_FILE
sed -i '/^SQL>/d' $OUTPUT_FILE
sed -i '/^Copyright/d' $OUTPUT_FILE

log "Monthly card generation process completed successfully."

# 发邮件
echo "Monthly card summary" | mailx -s "$NOW 一个月card 5000个" -a monthly_card_generation.csv -c "[email protected]" -c "[email protected]" [email protected]

exit 0

3. 调度执行

0 9 1 * * /home/oracle/dbbat/monthly_card_generation.sh &> /dev/null

你可能感兴趣的:(Oracle,循序渐进,sed,&,awk,oracle,数据库)