2

大家好,我有一个问题希望你们能帮助我。我试图包括所有相关信息。我正在构建一个 perl 脚本,该脚本最终将遍历不同的 sqlloader 控制文件并将它们各自的 csv 数据导入到 oracle sql 数据库表中。我在循环它们之前测试多个控制负载。问题是,即使脚本连接到数据库并上传所有 csv 数据而我看不到任何问题,我也会收到错误消息。所有行都被考虑在内,日志并没有真正帮助:

 ================================================================================
 [root@sanasr06 scripts]# perl db_upload.pl
 connection made! Starting database upload...
 Error: Can't open import control_general to SQL DB : at db_upload.pl line 44
 ================================================================================

第44行是系统连接:

system ("sqlldr $userid\@$sid/$passwd control=@control_pools log=$log silent=all ") or $logger->logdie("Error: Can't open import control data to SQL DB :$!" );

我包括控制文件输出、perl 脚本和控制文件。(提到的跳过的文件是针对 csv 标头的:)

 SQL*Loader: Release 11.2.0.1.0 - Production on Tue Aug 14 12:32:36 2012
 Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.
 Control File:   /despliegue/san/project/sql_ctrl/general.ctl
 Character Set UTF8 specified for all input.

 Data File:      /despliegue/san/project/csv/Pools.csv
 Bad File:     /despliegue/san/project/logs/sql_error.bad
 Discard File: /despliegue/san/project/logs/sql_discard.dsc 
 (Allow all discards)

 Number to load: ALL
 Number to skip: 1
 Errors allowed: 50
 Bind array:     64 rows, maximum of 256000 bytes
 Continuation:    none specified
 Path used:      Conventional
 Silent options: FEEDBACK, ERRORS and DISCARDS

 Table I_GENERAL, loaded from every logical record.
 Insert option in effect for this table: TRUNCATE
 TRAILING NULLCOLS option in effect
 Column Name                  Position   Len  Term Encl Datatype
 ------------------------------ ---------- ----- ---- ---- ---------------------
 OBJECTID   (FILLER FIELD)           FIRST     *     ,  O(")  CHARACTER

 DESCRIPTION   (FILLER FIELD)         NEXT     *     ,  O(")  CHARACTER  

 SERIALNUMBER                         NEXT     *     ,  O(")  CHARACTER  

 PRODUCT_NAME                         NEXT     *     ,  O(")  CHARACTER   

 CONTROLLER_VERSION                   NEXT     *     ,  O(")  CHARACTER    

 NUMBER_OF_CONTROLLERS                NEXT     *     ,  O(")  CHARACTER    

 CAPACITY_GB                          NEXT     *     ,  O(")  CHARACTER    

 PRODUCT_CODE                         NEXT     *     ,  O(")  CHARACTER            

 value used for ROWS parameter changed from 64 to 15

 Table I_GENERAL:
 2512 Rows successfully loaded.
 0 Rows not loaded due to data errors.
 0 Rows not loaded because all WHEN clauses were failed.
 0 Rows not loaded because all fields were null.

 Space allocated for bind array:                 247680 bytes(15 rows)
 Read   buffer bytes: 1048576
 Total logical records skipped:          1
 Total logical records read:          2512
 Total logical records rejected:         0
 Total logical records discarded:        0

 Run began on Tue Aug 14 12:32:36 2012
 Run ended on Tue Aug 14 12:32:38 2012

==================================================== =================================

上述文件当然会缩短,但包含所有相关信息。这是 perl 脚本。

#!/usr/bin/perl
use strict;
use warnings;
use DBI;
use Log::Log4perl;
#this script loads multiple saved csv files into the database using the control files

################ Initialization #############################################
my $homepath = "/despliegue/san/project";

my $log_conf = "$homepath/logs/log.conf";
Log::Log4perl->init($log_conf)or die("Error: Can't open log.config Does it exist? $!");
my $logger = Log::Log4perl->get_logger();

################ database connection variables####
my ($serial, $model);
my $host="me.notyou33.safety";
my $port="1426";
my $userid="user";
my $passwd="pass";
my $sid="sid";
my $log="$homepath/logs/sql_import.log";

#Control file location
my @control_pools= "$homepath/sql_ctrl/pools.ctl";
my @control_general = "$homepath/sql_ctrl/general.ctl";
my @control_ports= "$homepath/sql_ctrl/ports.ctl";
my @control_replication = "$homepath/sql_ctrl/replication.ctl";

#######################Database connection and data upload #################
my $dbh = DBI->connect( "dbi:Oracle:host=$host;sid=$sid;port=$port", "$userid", "$passwd", 
{ RaiseError => 1}) or $logger->logdie ("Database connection not made: $DBI::errstr");

print " connection made! Starting database upload...\n";

system ("sqlldr $userid\@$sid/$passwd control=@control_general log=$log silent=all") or $logger->logdie("Error: Can't open import control_general to SQL DB :$!");

print "one done moving to next one\n";

system ("sqlldr $userid\@$sid/$passwd control=@control_pools log=$log silent=all ") or $logger->logdie("Error: Can't open import control data to SQL DB :$!");

system ("sqlldr $userid\@$sid/$passwd control=@control_ports log=$log  ") or $logger->logdie("Error: Can't open import control data to SQL DB :$!");

print "three done moving to last one\n";

system ("sqlldr $userid\@$sid/$passwd control=@control_replication log=$log silent=feedback ") or    $logger->logdie("Error: Can't open import control data to SQL DB :$!");

print "................Done\n";
############################################################################
$dbh->disconnect;

==================================================== ================================= 控制文件:

OPTIONS (SKIP=1) 
LOAD DATA
CHARACTERSET UTF8
INFILE      '/despliegue/san/project/csv/Pools.csv'
BADFILE     '/despliegue/san/project/logs/sql_error.bad'
DISCARDFILE '/despliegue/san/project/logs/sql_discard.dsc'
TRUNCATE INTO TABLE I_GENERAL 
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY "\"" 
 TRAILING NULLCOLS
( 
OBJECTID FILLER,
DESCRIPTION FILLER,
SERIALNUMBER,
PRODUCT_NAME,
CONTROLLER_VERSION,
NUMBER_OF_CONTROLLERS,
CAPACITY_GB,
PRODUCT_CODE,
)
4

4 回答 4

1

Logdie哪个应该有logdie,AFAIU

于 2012-08-14T12:00:50.690 回答
1

system()返回wait调用的返回值,其中包括您执行的程序的返回值。如果一切顺利,这将是0. 这与 Perl 中几乎所有其他功能不同,您希望它们返回一些在布尔上下文中计算为 True 的值。因此,使用 or 运算符的常用错误处理无法正常工作。您可能想尝试这样的事情:

system ("sqlldr $userid\@$sid/$passwd control=@control_pools log=$log silent=all") == 0
    or $logger->logdie("Error: Can't open import control data to SQL DB :$?");

您可以在perldoc -f systemsystem()下的文档中阅读有关处理返回值的更多信息

于 2012-08-14T12:07:21.043 回答
1

问题是系统调用期望返回值 0 是“成功的”。您的 sqlldr 作业,如果它跳过或丢弃记录,将不会返回 0(我已经看到它返回 2,请检查文档以确定)。因此,除非您成功加载所有记录,否则您的 perl 脚本(如所写)将退出。

perl系统
sqlldr返回码

于 2012-08-14T12:26:07.053 回答
1

就我而言,我使用反引号(类似于系统)执行 sqlldr,这有助于我在变量中获得任何反馈。

my $sqlldr = "sqlldr userid=usr/pss\@TNS control=\'$controlfile\' log=\'$logfile\' silent=header,feedback";
$execution = `$sqlldr 2>&1`;

诀窍是 perl 中的返回值不是 0,您必须将该值右移 8 位以确保获得 0。在我的情况下,我执行以下操作:

# Get the returned code from the last execution
my $ret = $? >> 8;

if ($ret == 0) {
    $logger->info("Class DLA_Upload: All rows were successfully loaded");
}
elsif ($ret == 1) {
    die("Class DLA_Upload: Executing sqlldr returned the following error:\n$execution");
}
elsif ($ret == 2) {
    $logger->info("Class DLA_Upload: SQL*Loader was executed but some or all rows were rejected or discarded, please check $logfile for further information");
}
else {
    die("Class DLA_Upload: FATAL ERROR: sqlldr corrupted or not found");
}

为什么,在这里你有一个来自 Perl 僧侣的链接,它正确地解释了它。

于 2012-08-14T12:47:26.137 回答