2012-12-23 99 views
2

晚上好。MySQLi循环查询变量

我目前正在研究一个小型个人项目。它的目的是从后端数据库中检索大量值并将它们存储为变量。然后使用这些变量修改一些HTML5 Canvas对象的外观(在这种情况下,我使用的是弧线)。

请注意,数据库中的值是Text,因此我的绑定语句引用了这一点。我正在调用的查询(AVG,MIN,MAX)可以很好地处理字段存储数值数据时的值(这仅仅是由于另一个处理添加或更新数据的脚本 - 已经运行了MySQLi ,并使用Text是我的情况的最佳解决方案)。

现在,我用标准的MySQL查询达到了我想要的效果,但是它的代码很乱,随着数据库的增长,它的性能可能会变得很糟糕。出于这个原因,我想使用循环。我也觉得MySQLi的bind_param会更好的安全性。该页面不接受任何用户输入,仅用于显示,因此注入不太受关注,但在将来的某个时刻,我会将其扩展为允许用户控制显示的内容。

下面是我的原始MySQL PHP代码示例的示例;

$T0A = mysql_query('SELECT AVG(Temp0) FROM VTempStats'); // Average 
$T0B = mysql_query('SELECT MIN(Temp0) FROM VTempStats'); // Bottom/MIN 
$T0T = mysql_query('SELECT MAX(Temp0) FROM VTempStats'); // Top/MAX 
$T1A = mysql_query('SELECT AVG(Temp1) FROM VTempStats'); // Average 
$T1B = mysql_query('SELECT MIN(Temp1) FROM VTempStats'); // Bottom/MIN 
$T1T = mysql_query('SELECT MAX(Temp1) FROM VTempStats'); // Top/MAX 

$r_T0A = mysql_result($T0A, 0); 
$r_T0T = mysql_result($T0T, 0); 
$r_T0B = mysql_result($T0B, 0); 
$r_T1A = mysql_result($T1A, 0); 
$r_T1T = mysql_result($T1T, 0); 
$r_T1B = mysql_result($T1B, 0); 

if ($r_T0A == "") {$r_T0A = 0;} 
if ($r_T1A == "") {$r_T1A = 0;} 

if ($r_T0B == "") {$r_T0B = 0;} 
if ($r_T1B == "") {$r_T1B = 0;} 

if ($r_T0T == "") {$r_T0T = 0;} 
if ($r_T1T == "") {$r_T1T = 0;} 

这比原来更短的,因为有4×3集的查询(TEMP0,TEMP1,TEMP2,TEMP3,和最小值,最大值,平均为每个)的。请注意,最后的6 if语句只是为了确保在我的画布脚本尝试使用它们之前将空字段自动设置为0(请参见下文)。要在圆弧上显示该值,我会在我的画布脚本中使用此值(例如);

var endAngle = startAngle + (<?= $r_T0A ?>/36+0.02); 

它为我工作,显示什么是我期望的。

现在,在试图清理我的代码并转向循环和MySQLi时,我遇到了问题。对SQL和PHP都很新颖,我可以使用一些帮助。

这是我试过的;

$q_avg = "SELECT AVG(Temp?) FROM VTempStats"; 
    for ($i_avg = 0; $i_avg <= 3; ++$i_avg) 
    { 
     if ($s_avg = $mysqli->prepare($q_avg)) 
     { 
      $s_avg->bind_param('s',$i_avg); 
      $s_avg->execute(); 
      $s_avg->bind_result($avg); 
      $s_avg->fetch(); 
      echo $avg; 
     } 
    } 

注:mysqli是MySQLi的连接。我已将代码缩减为仅显示AVG查询循环,但MINMAX循环几乎完全相同。

很明显,这不起作用,因为它只为每组查询分配一个变量,而不是每个循环的4个变量。

正如你可以想象的,我想要做的是将所有12个值分配给单个变量,以便我可以在我的画布脚本中使用它们。我不完全确定我是如何去解决这个问题的。

我可以通过MySQLi回显单个值,或者我可以通过MySQLi查询数据库以更改或添加数据,但试图创建一个循环来完成我想要的MySQLi(甚至是MySQL),这是我需要的帮助。

+0

你有没有考虑动态生成的查询和使用单个查询,而不是很多疑问?如果没有,我可能会告诉你这是如何完成的。 –

+0

关于这一点:“请注意,最后的6条if语句仅仅确保那些为null的字段自动设置为0 ...”如果将列定义为NOT NULL DEFAULT'0'这样,空列将始终具有可预测的值,并且可以跳过所有if()语句! –

+0

@MichaelBerkowski:这可能是正确的建议! –

回答

1

从我读取您的代码时,您有固定数量的列并知道它们的名称,并且您正在将AVG(), MIN(), MAX()聚合应用于同一聚合组中的同一表,并且没有应用WHERE子句。因此,他们都可以在中完成一个查询,您只需从中获取一行。

SELECT 
    AVG(Temp0) AS a0, 
    MIN(Temp0) AS min0, 
    MAX(Temp0) AS max0, 
    AVG(Temp1) AS a1, 
    MIN(Temp1) AS min1, 
    MAX(Temp1) AS max1, 
    AVG(Temp2) AS a2, 
    MIN(Temp2) AS min2, 
    MAX(Temp2) AS max2, 
    AVG(Temp3) AS a3, 
    MIN(Temp3) AS min3, 
    MAX(Temp3) AS max3 
FROM VTempStats 

这可以在单个调用来完成对$mysqli->query(),所以你并不需要的prepare()开销没有参数结合是必要的。需要调用fetch_assoc()来检索单行,像上面所做的那样,列的别名类似a0, min0, max0, etc...

// Fetch one row 
$values = $result_resource->fetch_assoc(); 
print_r($values); 
printf("Avg 0: %s, Min 0: %s, Max 0: %s... etc....", $values['a0'], $values['min0'], $values['max0']); 

这些可拉成全球范围内与extract(),但我建议针对。保持它们在$values数组中使得它们的源更加明确。

+0

2个奇妙的答案,但这是最简单的工作。我想补充说,使用'$ query'作为你在那里列出的SQL,然后分配'$ stmt = $ mysqli-> query($ query); $ stmt-> execute;'并调用'$ values = $ stmt-> fetch_assoc();'正是需要的! –

1

正如你可以想象的,我想要做的是将所有12个值分配给单个变量,以便我可以在我的画布脚本中使用它们。我不完全确定我是如何去解决这个问题的。

了解。这是我会做的。

<?php // RAY_temp_scottprichard.php 
error_reporting(E_ALL); 
echo '<pre>'; 

// RANGE OF TEMPS 
$temps = range(0,3); 

// RANGE OF VALUES 
$funcs = array 
('A' => 'AVG' 
, 'B' => 'MIN' 
, 'T' => 'MAX' 
) 
; 

// CONSTRUCT THE QUERY STRING 
$query = 'SELECT '; 
foreach ($temps as $t) 
{ 
    foreach ($funcs as $key => $func) 
    { 
     $query .= PHP_EOL 
     . $func 
     . '(Temp' 
     . $t 
     . ') AS ' 
     . 'T' 
     . $t 
     . $key 
     . ', ' 
     ; 
    } 
} 

// DECLOP THE UNWANTED TRAILING COMMA 
$query = rtrim($query, ', '); 

// ADD THE TABLE NAME 
$query .= ' FROM VTempStats'; 

// ADD ANY ORDER, LIMIT, WHERE CLAUSES HERE 
$query .= ' WHERE 1=1'; 

// SHOW THE WORK PRODUCT 
var_dump($query); 

看到输出的查询字符串这里:http://www.laprbass.com/RAY_temp_scottpritchard.php

当您运行此查询,您将获取一个排,* mysql_fetch_assoc()*或等效的,它将拥有所有你想要的变量行,带有命名键。然后你可以使用这样的东西将变量名和值注入到脚本中。 http://php.net/manual/en/function.extract.php

PHP extract()允许使用前缀,因此您应该能够避免对现有脚本进行太多更改。

HTH,雷〜