【问题标题】:How can I add data from Oracle columns into a PHP array?如何将 Oracle 列中的数据添加到 PHP 数组中?
【发布时间】:2021-01-16 06:54:51
【问题描述】:

我有 PHP 代码从 CSV 文件中读取数据以填充到 HTML 表中。正在读取的 CSV 文件如下所示(示例;不是整个文件):

A,2020-06-01,1,15,0,0,99.5,problem,
B,2020-06-01,0,0,0,0,100,,
A,2020-06-02,0,0,0,0,100,,
B,2020-06-02,0,0,0,0,100,,
A,2020-06-03,0,0,0,0,100,,
B,2020-06-03,0,0,1,30,99.2,problem,
A,2020-06-04,0,0,0,0,100,,
B,2020-06-04,0,0,0,0,100,,
A,2020-06-05,0,0,0,0,100,,
B,2020-06-05,0,0,1,10,99.7,problem,
A,2020-06-06,0,0,0,0,100,,
B,2020-06-06,0,0,0,0,100,,
A,2020-06-07,0,0,0,0,100,,
B,2020-06-07,0,0,0,0,100,,
A,2020-06-08,1,60,0,0,98.9,problem,
B,2020-06-08,0,0,0,0,100,,

服务“A”和“B”每天记录价值。

用于处理 CSV 文件的代码如下所示:

<?php

$filename = "/var/tmp/dataset.csv";

if (($h = fopen($filename, "r")) !== FALSE) 
{
    $A_totals = array();
    $B_totals = array();
    $cols = array();
    $A_index = 1;
    $B_index = 1;
    $cols = array("service_name", "date", "nbr_out", "hrs_out", "nbr_dgrd", "hrs_dgrd", "pct_avail", "comments");

    // Loop through rows in CSV file
    while (($row = fgetcsv($h, 10000, ",")) !== FALSE) {
    // Assign variables and create summary arrays for each service
        $recordYear = strpos($row[1], $searchYear.'-');
        $recordMonth = strpos($row[1], '-'.$searchMonth.'-');
        
            if ($recordYear !== FALSE && $recordMonth !== FALSE) {
        
                if ($row[0] == 'A') {
                    $A_totals['item_' . $A_index++] = array_combine($cols, $row);
                }
                if ($row[0] == 'B') {
                    $B_totals['item_' . $B_index++] = array_combine($cols, $row);
                } 

            }
    
    }

    $A_nbr_out_totals = array_sum(array_column($A_totals, 'nbr_out'));
    $A_hrs_out_totals = array_sum(array_column($A_totals, 'hrs_out'));
    $A_nbr_dgrd_totals = array_sum(array_column($A_totals, 'nbr_dgrd'));    
    $A_hrs_dgrd_totals = array_sum(array_column($A_totals, 'hrs_dgrd'));
    $A_pct_avail_totals = array_sum(array_column($A_totals, 'pct_avail'));
    $A_pct_avail_total_count = count(array_column($A_totals, 'pct_avail'));
    $A_pct_avail_avg = round(( $A_pct_avail_totals / $A_pct_avail_total_count ), 4 );
    
    $B_nbr_out_totals = array_sum(array_column($B_totals, 'nbr_out'));
    $B_hrs_out_totals = array_sum(array_column($B_totals, 'hrs_out'));
    $B_nbr_dgrd_totals = array_sum(array_column($B_totals, 'nbr_dgrd'));    
    $B_hrs_dgrd_totals = array_sum(array_column($B_totals, 'hrs_dgrd'));
    $B_pct_avail_totals = array_sum(array_column($B_totals, 'pct_avail'));
    $B_pct_avail_total_count = count(array_column($B_totals, 'pct_avail'));
    $B_pct_avail_avg = round(( $B_pct_avail_totals / $B_pct_avail_total_count ), 4 );
}

代码读取 CSV 文件,并为给定月份/年份的 CSV 文件中的每个数字“列”提供服务总计。然后将这些总数传递到 HTML 表中以供服务显示。

我已以“对等”方式将 CSV 数据导出到 Oracle 表中。表中使用的列名与 CSV 文件使用的名称相似,不同之处在于每个 Oracle 表列的开头都添加了“IA_”前缀。

我的挑战:现在我使用 Oracle 表来引用数据,我在 PHP 代码中根据需要使用 OCI8。如果可能的话,我想保持 PHP 数组方法完整(据我所知它有效)。 OCI8 代码会读取 Oracle 表的每一行并将其添加到数组中以供其他数组命令 (array_combine/array_sum/array_map) 使用。

在尝试此操作时,我已将代码修改为如下所示:

<?php

    $A_totals = array();
    $B_totals = array();
    $cols = array();
    $A_index = 1;
    $B_index = 1;
    $cols = array("service_name", "date", "nbr_out", "hrs_out", "nbr_dgrd", "hrs_dgrd", "pct_avail", "comments");

$sql1 = "SELECT IA_SERVICE, TO_CHAR(IA_DATE, 'MM/DD/YYYY HH12:MI:SS AM') AS IA_DATE, IA_NBR_OUT, IA_HRS_OUT, IA_NBR_DGRD, IA_HRS_DGRD, IA_PCT_AVAIL, IA_COMMENTS FROM i_avail WHERE TO_CHAR(IA_DATE, 'Mon')='$searchMonth' AND TO_CHAR(IA_DATE, 'YYYY')='$searchYear'";

$stid1 = oci_parse($connect, $sql1);

$r = oci_execute($stid1);

    // Loop through rows in Oracle table
    while (($row = oci_fetch_array($stid1, OCI_BOTH+OCI_RETURN_LOBS))!= false) {
    // Assign variables and create summary arrays for each service
        
        if ($row['IA_SERVICE'] == 'A') {
        $A_totals['item_' . $A_index++] = array_combine($cols, $row);
        }
        if ($row['IA_SERVICE'] == 'B') {
        $B_totals['item_' . $B_index++] = array_combine($cols, $row);
        } 

    }
    

    $A_nbr_out_totals = array_sum(array_column($A_totals, 'nbr_out'));
    $A_hrs_out_totals = array_sum(array_column($A_totals, 'hrs_out'));
    $A_nbr_dgrd_totals = array_sum(array_column($A_totals, 'nbr_dgrd'));    
    $A_hrs_dgrd_totals = array_sum(array_column($A_totals, 'hrs_dgrd'));
    $A_pct_avail_totals = array_sum(array_column($A_totals, 'pct_avail'));
    $A_pct_avail_total_count = count(array_column($A_totals, 'pct_avail'));
    $A_pct_avail_avg = round(( $A_pct_avail_totals / $A_pct_avail_total_count ), 4 );
    
    $B_nbr_out_totals = array_sum(array_column($B_totals, 'nbr_out'));
    $B_hrs_out_totals = array_sum(array_column($B_totals, 'hrs_out'));
    $B_nbr_dgrd_totals = array_sum(array_column($B_totals, 'nbr_dgrd'));    
    $B_hrs_dgrd_totals = array_sum(array_column($B_totals, 'hrs_dgrd'));
    $B_pct_avail_totals = array_sum(array_column($B_totals, 'pct_avail'));
    $B_pct_avail_total_count = count(array_column($B_totals, 'pct_avail'));
    $B_pct_avail_avg = round(( $B_pct_avail_totals / $B_pct_avail_total_count ), 4 );

我这次尝试的结果反映了每个定义的值都为零,这不是预期的。

由于数据现在在 Oracle 中,我可能会为每个利用 COUNT 和 AVG 函数的变量添加额外的 SQL 语句……但这将是很多语句。如果将来增加额外的服务,SQL 语句的数量会相应增加。如果可能的话,我想避免这种情况……因此我希望我可以利用已经存在的代码。

这可能吗?如果没有,我可以尝试另一种不需要大量 SQL 语句的方法吗?

【问题讨论】:

    标签: php arrays oracle oci8


    【解决方案1】:

    发现我的 OCI8 修改代码存在问题。 /var/log/httpd/ssl_error_log 中报告了错误“PHP 警告:array_combine():两个参数应该有相同数量的元素”。在页面上添加一些调试后,我注意到虽然我的 $cols 数组被定义为使用七个元素,但 Oracle 返回的 $row 有 14 个元素。我调整了我的 $cols 数组也使用了 14 个元素,并且代码现在可以正常工作了。

    【讨论】:

      猜你喜欢
      • 2021-09-30
      • 2010-10-07
      • 2012-01-17
      • 2016-10-16
      • 2023-03-28
      • 2010-12-12
      • 2016-07-22
      • 1970-01-01
      相关资源
      最近更新 更多