PHP + Delphi + FireBird

我有一个问题来检索大量的数据与PHP +delphi9 +火鸟。

应用程序屏幕截图我在Delphi应用程序中有一个名为“检查”的button,当我点击button生成PHP Excel文件时,通过根据函数参数中指定的条件从Firebird中检索数据。

delphi程序:

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中执行了这个函数并进行了testing,对于大量的数据检索是很好的,但是当我整合到Delphibutton的时候,它不适用于大量的数据,但是如果我通过Delphi检索小量的数据生成excel文件。

PHP从Firebird获取数据并插入到sql server表中的文件:

 <?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(); } } ?> 

请给我一个解决scheme。

提前致谢!

您可以使用LIMIT:

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

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

SELECT * FROM your_table LIMIT your_table

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

SELECT * FROM your_table LIMIT your_table

这将显示logging250,251,252,253和254

delphi
首先你必须得到你的表的logging数。
在你的.php文件中用一个函数和一个非常简单的select来获得行数。

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){ [...] 

delphi

 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; 

由于我不知道哪个数据库表是父级,所以我只能在这里显示一个build议。
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; [...] 

就是这样

当然,你必须build立你的.xls文件数据的数据(追加不覆盖)