Although this was happening less after the bug above was closed it was still coming up once and a while.
So while working on another script I came across a solution using the prepare and execute methods in the pear DB class.
Unfortunately, this led to an invalid cursor state error message from the DB.
The issue seemed to have something to do with the open database connection being reused when the function was called. The function sending another select statement caused the invalid cursor state.
So....
A separate function to get the--in this case--locations in an array and return that:
Code:
// function to get a list of locations and put them in an array then returns that array
function get_locations(){
$locationsArray = array();
require_once('DB.php');
$dbl = DB::connect("odbc://XXXXXX:XXXXXX@/Winprism");
// ...and check for errors.
if (DB::iserror($dbl)) {
die($dbl->getDebugInfo());
};
$sqll = $dbl->prepare("
SELECT
Location.Description
FROM
Location
");
if (PEAR::isError($sqll)) {
die($sqll->getDebugInfo());
}
$ql =& $dbl->execute($sqll);
if (PEAR::isError($ql)) {
die($ql->getDebugInfo());
}
while ($ql->fetchInto($row)) {
$Location = $row[0];
$Location = trim($Location);
$locationsArray[] = $Location;
} // end while
return $locationsArray;
$dbl->disconnect();
} // end function definition for get_locations()
Then, instead of using a while loop as in the original version I used a foreach loop to iterate through this array. Only one connection to the ODBC database needed.
So the new version of the get_TY_Non_Merch function goes:
Code:
function get_TY_Non_Merch($Location, $FromDate, $ToDate){
require_once('DB.php');
$dbx = DB::connect("odbc://XXXXXX:XXXXXX/Winprism");
// ...and check for errors.
if (DB::iserror($dbx)) {
die($dbx->getDebugInfo());
}
$sql = $dbx->prepare("
SELECT TOP 1
((SUM((SalesHistoryDetail.SaleAmt)) + SUM((SalesHistoryDetail.SaleDisc))) - (SUM((SalesHistoryDetail.RtnAmt))
+ SUM((SalesHistoryDetail.RtnDisc))) - (SUM((SalesHistoryDetail.SaleDisc)) - SUM((SalesHistoryDetail.RtnDisc)))) AS NonMerch
FROM
SalesHistoryHeader
INNER JOIN
SalesHistoryDetail
ON
SalesHistoryHeader.SHMID = SalesHistoryDetail.SHMID
INNER JOIN
Location
ON
SalesHistoryHeader.LocationID = Location.LocationID
INNER JOIN
SalesTypes
ON
SalesHistoryDetail.TypeID = SalesTypes.TypeID
WHERE
SalesTypes.Description = 'Non-Merch'
AND
SalesHistoryHeader.PostDate >= '$FromDate'
AND
SalesHistoryHeader.PostDate <= '$ToDate'
AND
Location.Description = '$Location'
");
if (PEAR::isError($sql)) {
die($sql->getDebugInfo());
}
$q =& $dbx->execute($sql);
if (PEAR::isError($q)) {
die($q->getDebugInfo());
}
//$q = odbc_exec($db, $sql);
require_once('DB.php');
$db2 = DB::connect("mysql://XXXXXXX:XXXXXXXX@localhost/sales_by_department");
if (DB::iserror($db2)) {
die($db2->getDebugInfo());
}
while ($q->fetchInto($row)){
$field = $row[0];
} // end while
//odbc_fetch_into($q, $row);
$sql2 = "
INSERT INTO sales_by_department.dcc_sales VALUES ( 'NULL', 'NM', '-', '$field', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL' )
";
// this is a custom function that does what it
// says
send_query($sql2, $db2);
disconnect($db2);
disconnect($dbx);
//odbc_close($db);
return 0;
} // end function definition for get_TY_Non_Merch()
and that's executed in the foreach loop
Code:
$locationArray = get_locations();
foreach ($locationArray as $key=>$Location){
refresh_temp_table();
get_department_list();
get_sales_data_TY($Location, $TYDateFrom, $TYDateTo);
get_sales_data_LY($Location, $LYDateFrom, $LYDateTo);
get_departments_with_dcc_sales_TY($Location, $TYDateFrom, $TYDateTo);
get_departments_with_dcc_sales_LY($Location, $LYDateFrom, $LYDateTo);
get_TY_Non_Merch($Location, $TYDateFrom, $TYDateTo);
get_LY_Non_Merch($Location, $LYDateFrom, $LYDateTo);
get_totals();
print "<td>";
print_output($fBorder, $Location, $TYDateFrom, $TYDateTo, $LYDateFrom, $LYDateTo);
print "</td>";