如何将多个迭代提取的数据值连接成单个函数调用?

时间:2012-12-11 09:50:36

标签: php sql postgresql

这是我写过的最丑陋的东西,但我只是不知道如何做到这一点。 问题是我需要向依赖于使用迭代从另一个位置提取的信息的数据库提交SQL查询。

EG:我可以使用嵌套for循环提取数据,但是需要将整行重新组合在一起以对SQL进行插入查询。我试着暂时将单元格数据存储在变量中并按照这种方式进行操作,但这看起来很糟糕并且无法正常工作。

以下是我现在使用的代码:

请不要生气。我知道这太可怕了。我想变得更好。 另外,我已经把这条线(第98行)称为kiloline,因为它超过1000个字符。

$res1 = pg_query("INSERT INTO Project_Time_Sheet VALUES ('" . 
    $objWorksheet->getCellByColumnAndRow(0, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(1, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(2, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(3, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(4, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(5, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(6, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(7, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(8, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(9, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(10, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(11, $row)->getFormattedValue() . "', '" . 
    $objWorksheet->getCellByColumnAndRow(12, $row)->getFormattedValue() . "')");

请告诉我一个更好/更优雅/非愚蠢的方式来做到这一点。

4 个答案:

答案 0 :(得分:3)

所以,我将尝试直接改进此声明的汇编。这可能不能完全回答你的问题,但至少应该让你走上正确的道路。

$res1 = pg_query("INSERT INTO Project_Time_Sheet VALUES ('" . $objWorksheet->getCellByColumnAndRow(0, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(1, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(2, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(3, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(4, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(5, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(6, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(7, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(8, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(9, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(10, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(11, $row)->getFormattedValue() . "', '" 
    . $objWorksheet->getCellByColumnAndRow(12, $row)->getFormattedValue() . "')");

现在,这看起来不是更好吗?没有?有点可怕吗?遗憾。

假设:您将始终使用数字作为第一个参数调用getCellByColumnAndRow,它始终以1开头,并且可能在任何时候结束。而不是像 那样构建SQL,而是先使用循环来收集数据......

$max = 12;
$values = array();
foreach(range(1, $max) as $index)
    $values[] = "'" . $objWorksheet->getCellByColumnAndRow($index, $row)->getFormattedValue() . "'";

现在你可以将数组粘在一起。

$sql = 'INSERT INTO Project_Time_Sheet VALUES(' . join(', ', $values) .')';

嗯。 getFormattedValue是SQL安全的,对吗?如果不是怎么办?

还有一些改进。 PostgreSQL支持prepared statements。在这里使用它们可能是明智的。

再次,让我们盲目地假设事情是适度动态的。 PHP的PG扩展使用非标准占位符,这使我们的生活变得更加困难。让我们对数据收集进行一些小改动:

$max = 12;
$values = array();
foreach(range(1, $max) as $index)
    $values[ '$' . $index ] = "'" . $objWorksheet->getCellByColumnAndRow($index, $row)->getFormattedValue() . "'";

现在使用PG准备好的语句占位符对数组进行键控。

我们现在使用而不是值重新组装SQL:

$sql = 'INSERT INTO Project_Time_Sheet VALUES(' . join(', ', array_keys($values)) .')';

$sql现在看起来像

INSERT INTO Project_Time_Sheet VALUES($1, $2, $3 ...);

让我们准备并执行!

$sth = pg_prepare($dbh, '', $sql);
$res = pg_execute($dbh, '', array_values($values));

准备好的陈述给我们带来两件事:

  1. 添加了针对SQL注入的保护,
  2. 在循环中使用时可能带来的性能优势。准备一次,多次执行。

答案 1 :(得分:1)

就个人而言,我会使用数组和循环来执行此操作:

$values = array();
foreach (range(0, 12) as $i)
{
    $values[] = "'" . $objWorksheet->getCellByColumnAndRow($i, $row)->getFormattedValue() . "'";
}
$values = implode(', ', $values);
$sql = "INSERT INTO Project_Time_Sheet VALUES ({$values})";

答案 2 :(得分:1)

使用迭代添加多个条目并不是一个奇怪的要求,我不会说这本身很难看。但是,您似乎在安全方面存在问题,因为您没有转义参数。

我猜你准备好的陈述实际上就是你要找的东西。否则,你也可以使用pg_query_params使它更清洁(更安全!):

<?php
$statement = "INSERT INTO Project_Time_Sheet VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13 );";

pg_query_params( 
    $connection, 
    $statement, 
    array(
        $objWorksheet->getCellByColumnAndRow(0, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(1, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(2, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(3, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(4, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(5, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(6, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(7, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(8, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(9, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(10, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(11, $row)->getFormattedValue(),
        $objWorksheet->getCellByColumnAndRow(12, $row)->getFormattedValue()
    )
);

随着值的增加,您可能希望改为使用一个小循环:

<?php
$statement = "INSERT INTO Project_Time_Sheet VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13 );";

for($i = 0; $i <= 12; $i++) {
    $values[] = $objWorksheet->getCellByColumnAndRow($i, $row)->getFormattedValue();
}


pg_query_params( $connection, $statement, $values );

但是,我不得不承认这有点“闻起来”。也许你还没有足够规范你的数据库,或者情况可能需要它,但请再次检查一下模式,你可能犯了一个小错误。

答案 3 :(得分:0)

为什么不用循环完成查询?例如:

$query="INSERT INTO Project_Time_Sheet VALUES ('"; 
for($x=0; $x<$max;$x++){
    $query.=objWorksheet->getCellByColumnAndRow(0, $row)->getFormattedValue()."'";
    if($x<($max-1)){
          $query.=", '";
    }
}

$query.="');"