PHP + 德尔福 + Firebird

标签 php sql excel delphi firebird1.5

我在使用 PHP + Delphi 9 + Firebird 检索大量数据时遇到问题。

应用程序屏幕截图
我在 Delphi 应用程序中有一个名为 "checks"的按钮,当我单击该按钮时,它会根据函数参数中指定的条件从 Firebird 检索数据来生成 PHP Excel 文件。

德尔福程序:

procedure TfrmTransactions.dxBarButton2Click(Sender: TObject); //action click 
var ids: string;
  DateFrom, DateTo: string;
begin
  ids:='1';
  datefrom  := FormatDateTime('yyyy"/"mm"/"dd', dateStart.EditValue);
  dateto    := FormatDateTime('yyyy"/"mm"/"dd', dateEnd.EditValue);
  DBModule.SendRequest('checkFlow=' + Ids + '&startdate=' + datefrom + '&enddate=' + dateto, 'CheckFlow.xls');

end;

注:* 以上代码通过调用excelexport.php文件中的php方法checkFlow执行,生成'CheckFlow.xls'
* checkFlow 是 excelexport.php 中的一个函数,请参阅下面的文件。

问题:

我在PHP中执行了该功能并进行了测试,它适用于小型和大量数据检索,但是当我集成到Delphi按钮单击时,它不适用于大量数据但是如果我通过Delphi检索少量数据生成excel文件。

从 firebird 获取数据并插入 sql server 表的 PHP 文件:
<?php
require_once('class.pdo.firebird.php');
require_once('config.php');
require_once('xml.php');


function insertCheckFlowProduBanco($startdate,$enddate){
try{
$x=0;
$dateInArray = array();
$db = new PDOFirebird();
$datesql="SELECT DISTINCT  EXTRACT(YEAR FROM MV.FEC_VENCIMIENTO) ||'/'||
                substring(100+EXTRACT(MONTH from MV.FEC_VENCIMIENTO) from 2 for 2) ||'/'||
                substring(100+EXTRACT(DAY from MV.FEC_VENCIMIENTO) from 2 for 2)   AS FECHA
                FROM MOV_BANCOS  MV
                WHERE MV.CONCILIADO not in('A') AND  MV.MONTO>0 AND MV.KEY_BANCO=1
                AND MV.KEY_MOV_BANCO=1
                UNION  ALL
                SELECT DISTINCT  EXTRACT(YEAR FROM MV.FEC_VENCIMIENTO) ||'/'||
                substring(100+EXTRACT(MONTH from MV.FEC_VENCIMIENTO) from 2 for 2) ||'/'||
                substring(100+EXTRACT(DAY from MV.FEC_VENCIMIENTO) from 2 for 2)   AS FECHA
                FROM MOV_BANCOS  MV
                WHERE MV.CONCILIADO not in('A') AND MV.FEC_VENCIMIENTO >= '".$startdate."'
                AND MV.FEC_VENCIMIENTO <='".$enddate."' AND MV.MONTO>0 AND MV.KEY_BANCO=1"; 

    $dates = $db->query($datesql);
    while ( $row = $dates->fetch( PDO::FETCH_ASSOC ) ) {
    if($row['FECHA']!=null){
    $fecha= $row['FECHA'];  
    }
    $dateInArray[$x] = $fecha;
    $x++;   
}
$farmsql="SELECT DISTINCT MV.OBSERVACION AS NAME
FROM MOV_BANCOS MV
 WHERE MV.CONCILIADO not in('A') AND MV.KEY_BANCO=1 AND MV.KEY_MOV_BANCO=1
 UNION ALL
 SELECT DISTINCT MV.OBSERVACION AS NAME
FROM MOV_BANCOS MV 
WHERE MV.CONCILIADO not in('A') AND MV.FEC_VENCIMIENTO >= '".$startdate."'
AND MV.FEC_VENCIMIENTO <='".$enddate."' AND MV.MONTO>0 AND MV.KEY_BANCO=1";
$farms= $db->query($farmsql);
while ( $row = $farms->fetch( PDO::FETCH_ASSOC ) ) {
if($row['NAME']!=null){
$name=$row['NAME'];
}
foreach($dateInArray as $dateInArrayValue=>$valuedate){
$valuesql="SELECT  MV.OBSERVACION AS NAME,SUM(CAST(MV.MONTO as FLOAT)) as MONTO
                FROM MOV_BANCOS MV 
                WHERE MV.CONCILIADO not in('A') AND MV.FEC_VENCIMIENTO = '".$valuedate."'
                AND MV.OBSERVACION ='".$name."'
                AND MV.MONTO>0 AND MV.KEY_BANCO=1
                GROUP BY MV.OBSERVACION
                UNION ALL
                SELECT  MV.OBSERVACION AS NAME,SUM(CAST(MV.MONTO as FLOAT)) as MONTO
                FROM MOV_BANCOS MV 
                WHERE MV.CONCILIADO not in('A') AND MV.FEC_VENCIMIENTO = '".$valuedate."'
                AND MV.OBSERVACION ='".$name."'
                AND MV.MONTO>0 AND MV.KEY_BANCO=1
                GROUP BY MV.OBSERVACION";
$result= $db->query($valuesql);

$chequesql="SELECT  MV.NO_DOC_BANCO AS DOC
                FROM MOV_BANCOS MV 
                WHERE MV.CONCILIADO not in('A') AND MV.FEC_VENCIMIENTO = '".$valuedate."'
                AND MV.OBSERVACION ='".$name."'
                AND MV.MONTO>0 AND MV.KEY_BANCO=1
                UNION ALL
                SELECT  MV.NO_DOC_BANCO
                FROM MOV_BANCOS MV 
                WHERE MV.CONCILIADO not in('A') AND MV.FEC_VENCIMIENTO = '".$valuedate."'
                AND MV.OBSERVACION ='".$name."'
                AND MV.MONTO>0 AND MV.KEY_BANCO=1";

$cheque=$db->query($chequesql);
$y=0;
$chequearray=array();
while ( $row = $cheque->fetch( PDO::FETCH_ASSOC ) ) {
if($row['DOC']!=null){
$chequearray[]=$row['DOC'];
}
$y++;
}
$doc = implode(",", $chequearray);
$amount=array();
$i=0;
while ( $row = $result->fetch( PDO::FETCH_ASSOC ) ) {
$amount[$i]=$row['MONTO'];
}
if(($valuedate!=null) && ($name!=null) &&($amount[$i]!=0)){
$sql="INSERT INTO FLOWCHECK(SUPPLIER,BANK,DATE,AMOUNT,DOC)
VALUES('".$name."','PRODUBANCO','".$valuedate."','".$amount[$i]."','".$doc."')";
alexGetValues($sql);
}
$i++;
}
}
}catch(PDOException $e){
        return $e->getMessage();
}
}
?>

笔记:
* 我使用 Union ALL 是因为 firebird 在检索数据时为第一列返回 null。
* 我从 Firebird 获取数据并插入到 sql server 中。
* 存储在 sql server 表中的数据然后显示在 Excel 中
* 下面是 checkFlow 代码。

excelexport.php:(checkFlow)
<?php
require_once('Spreadsheet/Excel/Writer.php');
require_once('flowCheck.php');
ini_set('max_execution_time', 300);


function checkFlow($startdate,$enddate,$externalfile=''){

  $xls = new Spreadsheet_Excel_Writer();
  $xls->send('CheckFlow.xls');
  $formats = array(
 'space' => array('align' => 'center'),
 'title'    => array('size' => 14, 'bold' => 1, 'align' => 'center', 'color' => 'black', 'fgcolor' => array(224, 224, 224)),
 'left'     => array('size' => 10, 'align' => 'left','left' => 1, 'right' => 1, 'top' => 1, 'bottom' => 1),
 'center'   => array('size' => 10, 'align' => 'center','left' => 1, 'right' => 1, 'top' => 1, 'bottom' => 1),
 'right'   => array('size' => 10, 'align' => 'right','left' => 1,'right' => 1, 'top' => 1, 'bottom' => 1,'width' => 100),
 'header' =>   array('size' => 10, 'bold' => 1, 'align' => 'center','fgcolor' => array(255, 205, 160),'bottom' => 1,'left' => 1, 'right' => 1, 'top' => 1),
 );
   $colFormats = createFormats(&$xls, &$formats);

 insertCheckFlowProduBanco($startdate,$enddate);
$banksql="SELECT DISTINCT BANK FROM FLOWCHECK
            WHERE  CONVERT(VARCHAR,DATE,111)>='".$startdate."' 
            AND CONVERT(VARCHAR,DATE,111)<='".$enddate."'";

$banks=new AlexMSSQLDataset($banksql);
$bankarray=array();

while($banks->moveNext()){
 $bankarray[]=$banks->getFieldValue('BANK');
}

 foreach($bankarray as $val){
  $rowHeader=7;$colHeader=0;
  $col=0;
 $row=9;
 $sheet =&$xls->addWorksheet($val);
 $sheet->writeRow(1,1,array('Flujo de Cheques  ','','',''),&$colFormats['title']);
 $sheet->mergeCells(1,1,1,7);
 $datesql=" SELECT DISTINCT Convert(varchar,Date,111) AS Date,DATENAME(dw,Date) as Day
    FROM FLOWCHECK
    where convert(varchar,date,111)>='".$startdate."'
    and convert(varchar,date,111)<='".$enddate."'
    and bank='".$val."'";

 $dates=new AlexMSSQLDataset($datesql);

 $sheet->writeRow($rowHeader++, $colHeader, array('Banco','Farm'), &$colFormats['header']);
 $sheet->setColumn(0,0,30);
 $sheet->setColumn(1,1,60);
 $col1=2;
 $x=0;
  $dateInArray = array();
 while ($dates->moveNext()){
 $day=$dates->getFieldValue('Day');

 if( $day == 'Monday'){
    $day='Lunes';
 }else if( $day == 'Tuesday'){
    $day='Martes ';
 }else if( $day == 'Wednesday'){
    $day='Miércoles  ';
 }else if( $day == 'Thursday'){
    $day='Jueves  ';
 }else if( $day == 'Friday'){
    $day='Viernes';
 }else if( $day == 'Saturday'){
    $day='Sábado  ';
 }else if( $day == 'Sunday'){
    $day='Domingo ';
    }
 $sheet->write($rowHeader-1,$col1++,$day.' '.$dates->getFieldValue('Date'),&$colFormats['header']); 
 $dateInArray[$x] = $dates->getFieldValue('Date');
 $col1=2;
 foreach($dateInArray as $dateInArrayValue=>$valuedate){
  $sheet->mergeCells($rowHeader-1,$col1,$rowHeader-1,$col1+1);
  $sheet->write($rowHeader,$col1++,'Cheque No',&$colFormats['header']);
  $sheet->write($rowHeader,$col1++,'Value',&$colFormats['header']);
  }
 $x++; 
 $sheet->setColumn(1,$col1,25);
 }

  $farmsql="SELECT DISTINCT supplier,bank FROM flowCheck
    where convert(varchar,date,111)>='".$startdate."'
    and convert(varchar,date,111)<='".$enddate."' 
    and bank='".$val."'
    order by bank ";
 $farms=new AlexMSSQLDataset($farmsql); 
 while($farms->movenext()){
  $bank=$farms->getFieldValue('bank');
  $name=$farms->getFieldValue('supplier');
  $sheet->write($row,$col++,$bank,$colFormats['left']);
  $sheet->write($row,$col++,$name,$colFormats['left']);
  foreach($dateInArray as $dateInArrayValue=>$valuedate){
   $valuesql="SELECT supplier,amount,doc FROM flowCheck
    where convert(varchar,date,111)='".$valuedate."'
     and supplier='".$name."'
    and bank='".$val."'  ";

 $values=new AlexMSSQLDataset($valuesql);
 while($values->moveNext()){
 $farmvalues=$values->getFieldValue('amount');
 $chequenumber=$values->getFieldValue('doc');
 }
  if($values->getFieldValue('amount')!= null){
  $sheet->write($row,$col++,$chequenumber,$colFormats['left']);
 $sheet->write($row,$col++,round($farmvalues,2),$colFormats['left']);

 }else{
 $sheet->write($row,$col++,0,$colFormats['left']);
  $sheet->write($row,$col++,0,$colFormats['left']);
 }
}

 $col=0;
 $row++;
 $auxrow=$rowHeader+3;
 $auxcol=$col;
 }

  $sheet->writeRow($row, $auxcol, array('Total'), &$colFormats['header']);
 foreach($dateInArray as $dateInArrayval){
  $sheet->write($row, $auxcol+3,'=SUM('.$xls->rowcolToCell($auxrow-2,$auxcol+3).':'.$xls->rowcolToCell($row-1,$auxcol+3).')', &$colFormats['left']);
  $auxcol=$auxcol+2;

 $sheet->setMargins(0.40);
 $sheet->fitToPages(1, 0);
 $sheet->hideGridLines();
 $sheet->insertBitmap(0, 0, SHAREDPATH.'\\logo-reports.bmp', 3, 3);
 }
 } 
$xls->close();

}


if (!isset($_GET['noresponse']))
{
    $successauth = true;

        if (($_GET['client']) and ($_GET['auth']))
        {
        $client = intval($_GET['client']);
        $auth = intval($_GET['auth']);

        $userdata = new AlexMSSQLDataset('select AuthNumber from WebAuth where ID='.$client);
        $userdata->moveNext();
        alexGetValues('delete from WebAuth where ID='.$client);

        if ($userdata->getFieldValue(0) == $auth)
        {
            $successauth = true;
        }
    }

        if ($successauth)
        {

        if($_GET['checkFlow']){
            $startdate = $_GET['startdate'];
            $enddate = $_GET['enddate'];
            checkFlow($startdate,$enddate);
        }
        }
        else
        {
                $xls = new Spreadsheet_Excel_Writer();
                $xls->send('alert.xls');
                $sheet =& $xls->addWorksheet('Alert');

                $sheet->mergeCells(0, 0, 2, 0);

                if (file_exists(SHAREDPATH.'\\authalert.bmp'))
                {
            $sheet->insertBitmap(0, 0, SHAREDPATH.'\\authalert.bmp', 3, 3);
                }

                $sheet->write(0, 1, 'Authentication failed');
                $sheet->write(1, 1, 'You are not granted to view this report');

                $sheet->hideGridLines();

                $xls->close();
                exit();
        }
}




?>

请给我一个解决方案。

提前致谢!

最佳答案

您可以使用 LIMIT :

限制用于将您的 MySQL 查询结果限制在指定范围内。您可以使用它来显示前 X 个结果,或显示 X - Y 结果的范围。

它被表述为限制 X、Y,并包含在查询的末尾。 X 是起点(记住第一条记录是 0),Y 是持续时间(要显示多少条记录)。
也称为:范围结果
例子:

your_table中选择*限制 0, 250

这将显示来自数据库的前 250 个结果。

your_table中选择*限制 250, 5

这将显示记录 250、251、252、253 和 254

德尔福
首先,您必须获取表的记录数。
在您的 .php 文件中使用一个函数和一个非常简单的选择来获取行数。

php

<?php
require_once('class.pdo.firebird.php');
require_once('config.php');
require_once('xml.php');

if (isset($_REQUEST['action']) {
    if ($_REQUEST['action']=='getRCount') {
      getrowcount($_REQUEST['startdate'],$_REQUEST['enddate']);
      exit;
    }
 }

function getrowcount($startdate,$enddate) { 
// PSEUDO
connect to PDO
//do a simple select not select *
$sql="SELECT .... WHERE  CONVERT(VARCHAR,DATE,111)>='".$startdate."' 
        AND CONVERT(VARCHAR,DATE,111)<='".$enddate."'";
$res=new AlexMSSQLDataset($sql);
echo $res->num_rows;
 }

function insertCheckFlowProduBanco($startdate,$enddate){
[...]

德尔福
function TfrmTransactions.getrowcount(datefrom,dateto:integer): integer;
// PSEUDO
var
conStr : ansistring;

begin // here with a request to your .php file on the server
      // get the max rowcount 
conStr := 'getDataFromFirebird.php?action=getRCount'+
          '&startdate=' + datefrom + '&enddate=' + dateto;
connect to server 'http://myserver/myApp/'+conStr; 
result := response;
end;

procedure TfrmTransactions.dxBarButton2Click(Sender: TObject);
var Ids: string;
DateFrom, DateTo: ansistring;
maxcount : integer;
Limitfrom,LimitCount,conStr : ansistring;
begin
Ids:='1';
DateFrom  := FormatDateTime('yyyy"/"mm"/"dd', dateStart.EditValue);
DateTo    := FormatDateTime('yyyy"/"mm"/"dd', dateEnd.EditValue);    

  maxcount:=getrowcount(DateFrom, DateTo); 
  LimitFrom  := 0;
  LimitCount := 250;

  while LimitFrom < maxcount do begin

  if (LimitFrom + LimitCount) > maxcount then 
         LimitCount := LimitFrom + LimitCount - maxcount;

  conStr := 'checkFlow=' + Ids + 
            '&startdate=' + datefrom + 
            '&enddate=' + dateto +
            '&LimitFrom=' + intToStr(LimitFrom)+
            '&LimitCount=' + intToStr(LimitCount);

  DBModule.SendRequest(conStr,'CheckFlow.xls');
  LimitFrom := LimitFrom + LimitCount;
  end;
 end;

由于我不知道哪个数据库表是父表,我只能在这里给出一个建议。
php
[...]
$xysql="SELECT  ....
                ....
                FROM MOV_BANCOS  MV
                WHERE MV.CONCILIADO not in('A') AND MV.FEC_VENCIMIENTO >= '".$startdate."'
                AND MV.FEC_VENCIMIENTO <='".$enddate."' AND MV.MONTO>0 AND MV.KEY_BANCO=1 
                LIMIT ".$LimitFrom.", ".$LimitCount;
[...]

类似的东西

当然,您必须按数据构建 .xls 文件数据(追加而不是覆盖)

关于PHP + 德尔福 + Firebird ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25001743/

相关文章:

php - 安装 Composer

excel - 使用 VBA 修改动态名称

vba - 通过 CutePDF Writer 打印所有工作表

vba - 如何以编程方式使用 Excel 图表中的每个第 n 个单元格

php - 检查提交值是否在数组中?

php - 在没有 dl() 函数的情况下动态加载 php 扩展?

php - 将 php 数组传递给 sql 查询

php - 计数表中的成员数不能超过一个

mysql - 每组中具有最大值的行

mysql - 如何在一个查询中获取当前ID的当前和以前的ID(mysql)