为啥查询不返回值?

Posted

技术标签:

【中文标题】为啥查询不返回值?【英文标题】:Why is the query not returning values?为什么查询不返回值? 【发布时间】:2021-10-26 14:18:38 【问题描述】:

我正在将我的 perl 脚本从旧版本迁移到从 v5.8.4 到 Perl 版本 (v5.16.3) 的过程中,遇到了查询未获取结果的问题。

在查询返回时测试了以下场景

多行单列 -> 工作正常 单行单列 -> 工作正常 多行多列 -> 不工作 单行多列 -> 不工作

不确定发生了什么。它不是抛出错误,而是返回 0 条记录

my $sth;
        my $prepareCapture = capture_merged
        
            $sth = $dbh->prepare($self->_generatedSQL);
        ;
        $self->addProcessLogMessage($prepareCapture) if defined $prepareCapture;
        if (!defined $sth)
        
            $self->addProcessLogMessage('[PWX.extractPWXFile]: DBI::errstr = ' . $DBI::errstr);
            $self->addErrorMessage('PWX.extractPWXFile', 'Prepare of generated SQL against the PWX database failed');
            return -1;
        
        
        # Execute generated SQL against the PWX database
        $self->addProcessLogMessage('[PWX.extractPWXFile]: Executing generated SQL against PWX database');
        my $executeRC;
        my $executeCapture = capture_merged 
        
            $executeRC = $sth->execute();
        ;
        
        $self->addProcessLogMessage(sprintf('[PWX.Debugging sth Value-->%s',$sth));
        $self->addProcessLogMessage(sprintf('[PWX.Debugging executeCapture -->%s',$executeCapture));    
        $self->addProcessLogMessage(sprintf('[PWX.Debugging executeRC Val -->%s',$executeRC));  

        $self->addProcessLogMessage($executeCapture) if defined $executeCapture;
        if (!defined $executeRC)
        
            $self->addProcessLogMessage('[PWX.extractPWXFile]: DBI::errstr = ' . $DBI::errstr);
            $self->addErrorMessage('PWX.extractPWXFile', 'Execution of generated SQL against the PWX database failed');
            return -1;
        
        
        # Store details in local variables
        my $exportFileNm = PCF::Helpers::PathHelper->resolveExportFile($self->_srcSysCd,$self->_fileNm);
        my $fileDelimiter = $self->_fileDelimiter;
        my $fileDetailType = $self->_fileDetailType;
        my $recordCount = 0;
        # Open the export file, ready for writing to
        $self->addProcessLogMessage('[PWX.extractPWXFile]: Opening target object file');
        $self->addProcessLogMessage(sprintf('[PWX.extractPWXFile]: Export File = %s', $exportFileNm));
        if (open(EXPORT_HANDLE, sprintf('> %s', $exportFileNm)))
        
            # Output Header Record
            $self->addProcessLogMessage('[PWX.extractPWXFile]: Outputting Header Record to target object file');
            print EXPORT_HANDLE $self->_fileHeaderType
                              , $fileDelimiter
                              , $self->_fileRunNbr
                              , $fileDelimiter
                              , $self->_fileRunDt
                              , $fileDelimiter
                              , $self->_fileDescription
                              , $fileDelimiter
                              , $self->_runtimeParameters->'ProcInstId'
                              , "\n";
            
            # Fetch the resultset and output a Detail Record
            my $refRowArray;
            my $colIndex;
            my $colData;
            my $colOutput;
            my $colOutput1;
            my $colOutput2;
            my $colOutput3;
            $self->addProcessLogMessage('[PWX.extractPWXFile]: Outputting Detail Record(s) to target object file');
            while (1)
            
                $refRowArray = $sth->fetchrow_arrayref();
                last if !defined $refRowArray;
                
        # Iterate through the columns and build a hash for output
                print EXPORT_HANDLE $fileDetailType;
                $colIndex = 0;
                $colOutput1 = '';
                $colOutput2 = '';
                $colOutput3 = '';                
                foreach $colData (@$refRowArray)
                
                    # Perform left and right TRIM inline
                    $colOutput = $colData;
                    $colOutput =~ s/^\s+//;
                    $colOutput =~ s/\s+$//;
                    
                    # Replace CRLF, CR, LF and Pipes with a space
                    $colOutput =~ s/(\r\n|\r|\n|\|)/ /g;
                    
                    # If the column data has not returned a NULL value
                    # but rather contains all blanks then output a single blank
                    if ((defined $colData)
                         && (length($colOutput) == 0))
                    
                        $colOutput = ' ';
                    
                    
                    # If the first column, which is DTL__CAPXTIMESTAMP, format into ANSI standard
                    # Does not apply to sources that have EffStrtTs, RecTpCd as first 2 columns.
                    if ($colIndex == 0 && $self->_srcHasProcCols eq 'N')
                    
                        $colOutput = substr($colOutput, 0, 4)
                                   . '-'
                                   . substr($colOutput, 4, 2)
                                   . '-'
                                   . substr($colOutput, 6, 2)
                                   . ' '
                                   . substr($colOutput, 8, 2)
                                   . ':'
                                   . substr($colOutput, 10, 2)
                                   . ':'
                                   . substr($colOutput, 12, 2)
                                   . '.'
                                   . substr($colOutput, 14, 6);
                    
                    # If the extract is incremental, substitute capx_action values of "I" and "U" for "M"
                    elsif (($incrementalLoad == 1) && ($colIndex == 1))
                    
                        if ($colOutput eq 'I' || $colOutput eq 'U')
                        
                            $colOutput = 'M';
                        
                    
                    
                    # If the extract is bulk VSAM DFSORT, substitute RecTpCd value 'F' with the derived value from REC_TYP_CDE column.
                    # REC_TYP_CDE column is at the end of the record, so do not write to file until end of record is reached.
                    if ($attrDfSortFlag eq 'Y')
                    
                       #keep the column values in two strings
                       if ($colIndex > 1)
                       
                          $colOutput3 .= $fileDelimiter . $colOutput;
                       
                       elsif ($colIndex == 0)
                       
                          $colOutput1 = $colOutput;
                       
                       
                       if ($colIndex == $#$refRowArray)
                       
                          #derive RecTpCd value: 1 insert, 2 update, 3 delete
                          if (($colOutput == 1) || ($colOutput == 2))
                          
                             $colOutput2 = 'M';
                          
                          elsif ($colOutput == 3)
                          
                             $colOutput2 = 'D';
                          
                          else 
                             
                     if (!defined $colOutput)
                     
                                $colOutput2 = 'Null';
                             
                             else
                             
                                $colOutput2 = $colOutput;
                             
                             
                     $self->addErrorMessage('PWX.extractPWXFile', "VSAM DFSORT File: Invalid REC_TYP_CDE value from source. expecting 1,2 or 3 but received $colOutput2");
                     return -1;
                          
                          
                          #append the strings to make the record
                          print EXPORT_HANDLE $fileDelimiter, $colOutput1, $fileDelimiter, $colOutput2, $colOutput3;
                       
                    
                    else
                    
                       print EXPORT_HANDLE $fileDelimiter, $colOutput;
                    
                    
                    # Increment the column counter
                    $colIndex++;
                
                print EXPORT_HANDLE "\n";
                
                # Increment the record counter
                $recordCount++;
            

           # Check if there is any error while fetching. fail if there is.
       if ($DBI::err)
       
           $self->addErrorMessage('PWX.extractPWXFile', "Connection to database lost due to following error: $DBI::errstr");
           $self->addErrorMessage('PWX.extractPWXFile', "The following number of records were extracted before exiting : $recordCount ");
           return -1;
       

查询:

SELECT  col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11, col12,
        col13, col14, col15, col16, col17, col18, col19, col20, col21, col22
FROM mmm.cont
WHERE  datets >= DATEADD(HOUR,-2,'2021-06-17 14:30:40.110000')
AND datets < '2021-07-22 20:05:32.620000'
AT ISOLATION READ COMMITTED

【问题讨论】:

请显示所有 Perl 代码,而不仅仅是循环。显示调用查询以设置$sth 的代码。你在做什么错误检查? 更新到 8 年前的 Perl 版本似乎有点奇怪。为什么不升级到更新的版本? 添加完整代码 【参考方案1】:

返回 0 条记录

你怎么知道的?如果返回一些行或不返回行,您向我们展示的代码没有什么不同。我怀疑您为了与我们共享代码而过度简化了代码,并在此过程中删除了导致您的问题的部分。

我认为这不会导致您的问题,但我只是指出您当前的代码可以简化为:

while ($refRowArray = $sth->fetchrow_arrayref()) 
  # do nothing

【讨论】:

嗨,戴夫,我放了一些日志,打印返回的记录数。在这种情况下,它不返回任何记录。但是,如果我用简单的查询替换它,说我知道将返回 1 条记录,那么日志记录还指示它的重新调整记录,并且在 while 循环内我正在写入文件,因此它也在写入文件。 即使我用简单查询替换选择查询中的 2 列而不是 1 列,即使它失败了。如果 Select 查询有超过 1 列,则它不会从 db 返回任何内容。 您好,非常感谢您对此的任何帮助。我是 perl 脚本的新手,无法继续。请帮忙!!!

以上是关于为啥查询不返回值?的主要内容,如果未能解决你的问题,请参考以下文章

从 Access 中的另一个表返回值时,为啥我的查询运行如此缓慢?

为啥我的 For 循环在 EJS 节点 js 中只返回一个值?

为啥我从 Dapper 返回的对象具有 null 和默认属性值?

mybatis 查询一对多 集合中没有值为啥

为啥 withLatestFrom 不返回最新值?

为啥 main() 函数不返回浮点值?