0

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

EG:我可以使用嵌套的 for 循环提取数据,但随后需要将一整行重新组合在一起以对 SQL 进行插入查询。我尝试将单元格数据临时存储在变量中并这样做,但这看起来也很糟糕并且不起作用。

这是我现在使用的代码:

请不要生气。我知道这很糟糕。我想变得更好。顺便说一句,我把这条线(第 98 行)称为千线,因为它有 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

4 回答 4

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) .')';

唔。 getFormattedValueSQL 安全的,对吗?如果不是呢?

还是有一些改进的地方。PostgreSQL 支持准备好的语句。在这里使用它们可能是明智的。

同样,让我们​​盲目地假设事物是适度动态的。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. 在循环中使用时的潜在性能优势。一次准备,多次执行。
于 2012-12-11T09:59:24.260 回答
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})";
于 2012-12-11T09:58:43.157 回答
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 );

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

于 2012-12-11T10:00:34.820 回答
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.="');"
于 2012-12-11T10:01:52.910 回答