【问题标题】:How to pass parameters from Perl script to SQL script and execute it from Perl script?如何将参数从 Perl 脚本传递到 SQL 脚本并从 Perl 脚本执行?
【发布时间】:2021-02-15 01:09:23
【问题描述】:

我在 Linux 环境中使用 Informix 作为数据库。 我有一个应该执行 SQL 脚本的 Perl 脚本。在执行之前,它还应该将所有参数传递给 SQL 脚本。

我不知道如何将参数传递给 .sql 脚本? 它也可以运行,但出现以下错误。

DBD::Informix::st fetchrow_array failed: SQL: -400: Fetch attempted on unopen cursor. at startSelectQuer.pl 

我怎样才能意识到这一点?

selectQuer.sql

DROP TABLE IF EXISTS tempTable;
SELECT * FROM 'informix'.systables INTO TEMP tempTable;

DROP TABLE IF EXISTS magic_ant;
 select * from  del_new
    where
       id    = $i_id       and
       year  = $i_year     and
       month = $i_month              
    into 
        temp magic_ant; 

    
    DROP TABLE IF EXISTS magic_buck;
    select * from  upper_new
    where
       id    = $i_id       and
       year  = $i_year     and
       month = $i_month              
    into 
        temp magic_buck; 

DROP TABLE IF EXISTS alleMagic;
select  * from  magic_ant
union
select  * from  magic_buck
into temp alleMagic;    

select lname, fname, ext from alleMagic;

startSelectQuer.pl

       #!/usr/bin/perl
use strict;
use warnings;
use DBI;
    
my ($ID)    = $_[0];
my ($YEAR)  = $_[1];
my ($MONTH) = $_[2];

my $BEG_ANT=801 ; 
my $END_ANT=803 ; 
my $BEG_BRU=802 ; 
my $END_BRU=900 ;

my($dbh, $sth, $query);

######################################################################
my $database = "$ENV{DBNAME}";         
my $user ="";                                                                                          
my $pass ="";                                                                                       
$dbh = DBI->connect("dbi:Informix:$database", $user, $pass);                                                  
######################################################################
die "failed to connect to MySQL database:DBI->errstr()" unless($dbh);

my $sqlFile = "/SQLSCRIPTS/selectQuer.sql";
open (SQL, "$sqlFile")   or die("Can't open file $sqlFile for reading");

# Loop though the SQL file and execute each and every one.
while (my $line = <SQL>) {

  chomp $line;
  $line = join(' ',split(' ',$line));
  if ((substr($line,0,2) ne '--') and (substr($line,0,3) ne 'REM')) {
     if (substr($line,- 1,1) eq ';') {
            $query .= ' ' . substr($line,0,length($line) -1);
            # replace with value
            replaceQueryWithValue($query);
            
           $sth = $dbh->prepare($query, {'ix_CursorWithHold' => 1}) 
          or die "prepare statement failed: $dbh->errstr()";
           $sth->execute() or die "execution failed: $dbh->errstr()";

           my $rows = $sth->rows;
            #loop through each row of the result set, and print it.
           if ($rows > 0) {
            # Getting error here as: DBD::Informix::st fetchrow_array failed:
            # SQL: -400: Fetch attempted on unopen cursor. 
              while(my @row = $sth->fetchrow_array) {
                 print qw($row[0]\t$row[1]\t$row[2]\n);
              }
           } else
              {
                  print "\nThere is no result for query: $query\n" ;
              }
            $query = ' ';
      } else {
                 $query .= ' ' . $line;    
          }
  }
}

# close data connection
$sth->finish;
$dbh->disconnect;

sub replaceQueryWithValue{
   $query =~ s/i_id/$ID/ig;
   $query =~ s/i_year/$YEAR/ig;
   $query =~ s/i_month/$MONTH/ig;
}

【问题讨论】:

  • 尝试在字符串中插入对象函数调用可能不是一个好主意。 $dbh-&gt;errstr().
  • $sql 在您的准备语句中应该是一个字符串,而不是文件地址。
  • replaceQueryWithValue($query);$sth = $dbh-&gt;prepare($query, {'ix_CursorWithHold' =&gt; 1}) 两行之间,您应该安排打印$query 中的值(适当注释),以便您可以看到您在询问Informix DBMS 准备然后执行。 'fetch on an unopen cursor' 表示您正在执行的任何语句都不是 select 语句 — 文件中的许多语句不是返回行的 select 语句(INTO TEMP 子句意味着该语句不返回值) .
  • 注意select * from del_new where id = $i_id and year = $i_year and month = $i_month and into temp magic_ant; 等文件中的语句中的第三个and是错误的。您应该在第三个 and 之后包含另一个条件或删除它。
  • 如果您使用的表包含最少的模式和最少的数据集,以及预期和实际结果,这将很有帮助。这是为 SQL 相关问题创建 MCVE(Minimal, Complete, Verifiable Example — 或 MRE 或 SO 现在使用的任何名称)或 SSCCE(Short, Self-Contained, Correct Example)的一部分。强迫那些可能帮助你的人做这项工作并不容易得到答案——一般来说,人们不会这样做。

标签: linux perl unix informix sql-scripts


【解决方案1】:

在提出这样的问题时,如果您确切地告诉我们哪些地方没有按照您的预期工作,将会很有用。什么都没有发生?您收到错误消息吗?你的电脑会起火吗?

没有它,我们几乎是在猜测。但我很高兴在这里有一个猜测。我对 Informix 一无所知,但我猜您看到的是“prepare statement failed”错误。对吗?

如果是这样,您似乎正在尝试编译一个看起来像 SQLSCRIPTS/selectQuer.sql 的 SQL 语句 - 实际上,这是您应该打开并从中读取 SQL 语句的文件的名称。

【讨论】:

  • 它没有运行,我追踪到这条线阻止它继续。 $sth->execute($ID, $YEAR, $MONTH) or die "execution failed: $dbh->errstr()";
  • @itro:你做了我建议的改变吗?
  • 是的,我确实按照您所说的进行了更改。谢谢。
  • @itro:那么如果没有看到您的代码的当前版本,就很难提供更多帮助。或许你可以edit your question在最后添加。
【解决方案2】:

在执行 .sql 后,我使用了$sth-&gt;fetch 而不是$sth-&gt;fetchrow_array,如下所示。

  $sth = $dbh->prepare( "select * from alleMagic;" );
  $sth->execute;
    
   # Column binding is the most efficient way to fetch data
   my $rv = $sth->bind_columns(\$lname, \$fname, \$ext );
   while ($sth->fetch) {
       print "$lname, $fname, $ext \n";

   }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 2014-01-06
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 2010-09-26
    • 2022-09-27
    相关资源
    最近更新 更多