大家好,我有一个问题,希望你们能帮助我。我试图包含所有相关信息。我正在构建一个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”)或$ logger-> logdie(“错误:无法打开导入控制数据到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,
)
答案 0 :(得分:1)
Logdie
应为logdie
,AFAIU
答案 1 :(得分:1)
system()
返回wait
调用的返回值,其中包含您执行的程序的返回值。如果一切顺利,这将是0
。这与Perl中的几乎所有其他funktions不同,您希望它们返回一些在布尔上下文中计算为True的Value。因此,使用或运算符的常用错误处理不能正常工作。你可能想尝试这样的事情:
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 :$?");
下的文档中详细了解如何处理system()
的返回值
答案 2 :(得分:1)
问题是系统调用期望返回值0为“成功”。你的sqlldr作业,如果它跳过或丢弃一条记录,将不会返回0(我看到它返回2,检查文档是否确定)。因此,除非您成功加载所有记录,否则您的perl脚本(如所写)将退出。
perl system
sqlldr return codes
答案 3 :(得分: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");
}
为什么,here you have a link from Perl monks能够正确解释它。