PERL SCRIPT ERROR(DBD错误:错误可能接近< *>指示器atrror可能接近< *>指示符'char 53''插入

时间:2016-05-03 02:41:40

标签: perl

我在perl脚本下运行时遇到错误。任何人都可以帮忙解决这个问题吗?

    $ENV{PATH}= '/appl/OMS/scripts:/etc:/usr/bin:/usr/sbin:/b...';
    $ENV{PATH}= '/appl/OMS/scripts:/etc:/usr/bin:/usr/sbin:/bin:/usr/local/bin:/usr/local/opt/oracle/client/11.2.0.4/bin';
    $ENV{ORACLE_HOME} ='/usr/local/opt/oracle/client/11.2.0.4';
    $ENV{NLSPATH} = '/usr/lib/nls/msg/%L/%N:/usr/lib/nls/msg/%L/%N.cat';
    $ENV{CLASSPATH} = 'CLASSPATH=/usr/local/opt/oracle/client/11.2.0.4/jdbc/lib';
    $ENV{JAVA_HOME} = '/appl/OMS/Software/java';
    $ENV{PERL5LIB} = '/appl/OMS/perl/lib';

    use lib "/appl/OMS/perl/lib";

}

use DBI;
use DBD::Oracle;
use Data::Dumper;
use POSIX qw/strftime/;
use Switch;
use Term::ANSIColor;

print " Input the environment name:\n";
chomp($env=<STDIN>);

print " Input attuid:\n";
chomp($attuid=<STDIN>);

print " Input first name:\n";
chomp($fname = <STDIN>);

print " Input last name:\n";
chomp($lname= <STDIN>);
#chomp($lname);

my $dbInst="t1oms4d8.db.att.com";
my $dbUser="OMS1AT01utils";
my $dbPass="pswd4conn";
my $host = "t1oms5c1.sldc.sbc.com";
#$dsn= "dbi:oracle:T2OMS1D4.db.att.com:t2oms1c1.hydc.sbc.com:1521";
#$DBIconnect= DBI->connect($dsn,OMS0BT08utils,Pwd0wner1);

my $dbh=DBI->connect("dbi:Oracle:$dbInst", $dbUser, $dbPass);
my $sth = $dbh->prepare('create table temp_table1 as (select * from users where user_id like '%SR508W%')');
$sth-> execute();

print "test1";

my $sth = $dbh->prepare("update temp_table1 set user_id= ".$attuid.",  first_nm= ".$fname.", last_nm= ".$lname." where user_id like '%SR508W%' " );
$sth-> execute();

print "test2";

my $sth = $dbh->prepare("insert into users (select * from temp_table1)");
$sth-> execute();

my $sth = $dbh->prepare("insert into user_password(user_id,password1) values (".$attuid." ,(select PASSWORD1 FROM user_password where user_id like '%SR508W%'))");
$sth-> execute();

my $sth = $dbh->prepare("insert into user_role(user_id,role_id) values (".$attuid." ,'1')");
$sth-> execute();

my $sth = $dbh->prepare("select * from temp_table1");
$sth-> execute();

my $sth = $dbh->prepare("drop table temp_table1");
$sth->execute();

$sth->finish();

$dbh->commit or die $DBI::errstr;

我正在运行如下脚本:

  $ ./dbtrial.pl
     Input the environment name:
    oms1at01
     Input attuid:
    sm501u
     Input first name:
    swapnil
     Input last name:
    mahindrakar

错误消息如下:

DBD::Oracle::st execute failed: ORA-00904: "MAHINDRAKAR": invalid identifier (DBD ERROR: error possibly near <*> indicator at char 69 in 'update temp_table1 set user_id= sm501u,  first_nm= swapnil, last_nm= <*>mahindrakar where user_id like '%SR508W%' ') [for Statement "update temp_table1 set user_id= sm501u,  first_nm= swapnil, last_nm= mahindrakar where user_id like '%SR508W%' "] at ./dbtrial.pl line 45, <STDIN> line 4.
DBD::Oracle::st execute failed: ORA-00984: column not allowed here (DBD ERROR: error possibly near <*> indicator at char 53 in 'insert into user_password(user_id,password1) values (<*>sm501u ,(select PASSWORD1 FROM user_password where user_id like '%SR508W%'))') [for Statement "insert into user_password(user_id,password1) values (sm501u ,(select PASSWORD1 FROM user_password where user_id like '%SR508W%'))"] at ./dbtrial.pl line 50, <STDIN> line 4.
DBD::Oracle::st execute failed: ORA-00984: column not allowed here (DBD ERROR: error possibly near <*> indicator at char 47 in 'insert into user_role(user_id,role_id) values (<*>sm501u ,'1')') [for Statement "insert into user_role(user_id,role_id) values (sm501u ,'1')"] at ./dbtrial.pl line 52, <STDIN> line 4.
commit ineffective with AutoCommit enabled at ./dbtrial.pl line 58, <STDIN> line 4.
test1test2----- websphe cldv0011 /appl/OMS/scripts/trials ---

1 个答案:

答案 0 :(得分:4)

除了缺少#! /usr/bin/perl(或类似)行之外,您的脚本最明显的错误是在SQL状态中使用它们时没有正确引用变量。

解决此问题的最简单方法是在?语句中使用占位符($dbh->prepare())。然后在$sth-execute()

中提供实际值

例如:

my $sth = $dbh->prepare("update temp_table1 set user_id=?,
                         first_nm=?, last_nm=?
                         where user_id like '%SR508W%'");
$sth->execute($attuid,$fname,$lname);

这将自动引用需要引用的变量,这个示例似乎都是这个变量,因为它们都是字符串值。

此外,您只需要定义一次变量的范围。您不需要(也不应该)将my $sth= 每次时间设置为新值。在使用之前单独声明它(仅使用my $sth;,或者仅在您第一次使用它时声明它。

并添加一行或两行以分隔脚本的每个不同部分。这将使它比现在的丑陋文本墙更容易阅读。

最后,您可能需要考虑从命令行获取输入。这将使测试更多更容易,因为您可以使用shell的命令行历史记录和调用功能(即点击向上箭头并输入以再次执行相同的命令),而不必输入相同的四个值到每次运行它时的脚本。 e.g。

# environment name is first arg
my $env = shift;

# attuid is second arg
my $attuid = shift;

# First name is third arg
my $fname = shift;

# Last name is fourth arg
my $lname = shift;

像这样运行:

$ ./dbtrial.pl oms1at01 sm501u swapnil mahindrakar

(注意:这是非常原始的参数处理。如果你需要的东西比从命令行中获取前四个参数更好,请使用Getopt::StdGetopt::Long

就个人而言,我倾向于将脚本重写为更像这样的东西(更好的格式化,删除未使用的变量和模块,更好地使用DBI功能,以及改进的sql字符串构造):

#! /usr/bin/perl

use strict;
use warnings;

use lib "/appl/OMS/perl/lib";

use DBI;
use DBD::Oracle;

my ($env,$attuid,$fname,$lname);

# environment name is first arg
$env = shift;

# attuid is second arg
$attuid = shift;

# First name is third arg
$fname = shift;

# Last name is fourth arg
$lname = shift;

my ($dbInst, $dbUser, $dbPass, $host, $dbh, $sth, $sql, $where);

$dbInst="t1oms4d8.db.att.com";
$dbUser="OMS1AT01utils";
$dbPass="pswd4conn";

$dbh=DBI->connect("dbi:Oracle:$dbInst",$dbUser,$dbPass);

$where=' where user_id like \'%SR508W%\'';

$dbh->do('create table temp_table1 as (select * from users ' . $where . ')');

print "test1";
$sql = 'update temp_table1 set user_id=?,  first_nm=?, last_nm=?' . $where;
$sth = $dbh->prepare($sql);
$sth->execute($attuid,$fname,$lname);

print "test2";
$dbh->do('insert into users (select * from temp_table1)');

$sql = 'insert into user_password(user_id,password1) values (?,(select PASSWORD1 FROM user_password' . $where . ' ))';
$sth = $dbh->prepare($sql);
$sth->execute($attuid);

$sql = 'insert into user_role(user_id,role_id) values (?,?)';
$sth = $dbh->prepare($sql);
# does '1' need to be quoted here?  if field is a varchar or similar then yes, otherwise no.  assuming yes as in the original script.
$sth->execute($attuid,'1');

$dbh->do('select * from temp_table1');

$dbh->do('drop table temp_table1');

$sth->finish();
$dbh->commit or die $DBI::errstr;
$dbh->finish();