尝试通过pg_query_params

时间:2015-07-02 04:08:05

标签: php postgresql postgis

我曾经和Postgresql合作过一些,但我还是个新手。我通常默认创建太多的查询和黑客攻击以获得我需要的查询结果。这次我想写一些更简化的代码,因为我将处理一个大型数据库,代码需要尽可能简洁。

所以我有很多点数据,然后我有很多县。我有两个表,“县”和“ltg_data”(很多点)。我的目标是通读指定数量的县(如数组中所示)并确定每个县的落点数。我这样做的新手,重复和低效的方法是编写这样的查询:

$klamath_40_days = pg_query($conn, "SELECT countyname, time from counties, ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname");
$klamath_rows = pg_num_rows($klamath_40_days);

如果我为每个县运行如上所述的单独查询,它会给我很好的输出,但它重复且低效。我宁愿使用循环。最后我需要通过URL将params传递给查询。当我尝试在PHP中运行for循环时,我收到错误,说“查询失败:错误:列”杰克逊“不存在”,等等。这是循环:

$counties = array ('Jackson', 'Klamath');

foreach ($counties as $i) {
echo "$i<br>";

$jackson_24 = pg_query($conn, "SELECT countyname, time from counties,    ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname = ".$i." and time >= (NOW() - '40 DAY'::INTERVAL)");
$jackson_rows = pg_num_rows($result);

}

echo "$jackson_rows";

然后我研究了PHP中的pg_query_params功能,我认为这会有所帮助。但我运行这个脚本:

$counties = array('Jackson', 'Josephine', 'Curry', 'Siskiyou', 'Modoc', 'Coos', 'Douglas', 'Klamath', 'Lake');

$query = "SELECT countyname, time from counties, ltg_data where st_contains(counties.the_geom, ltg_data.ltg_geom) and countyname = $1 and time >= (NOW() - '40 DAY'::INTERVAL)";

$result = pg_query_params($conn, $query, $counties);

我收到此错误:查询失败:错误:绑定消息提供9个参数,但准备好的语句“”需要1个

所以我基本上想知道将参数传递的最佳方法(或者从URL传递param或者数组中的多个元素)到postgresql查询是什么?然后我想以有条理的方式回应总结果。

感谢您提供任何帮助。

2 个答案:

答案 0 :(得分:1)

要在循环中为多个值执行带有参数的查询,可以使用以下模式:

$counties = array('Jackson', 'Josephine', 'Curry');
$query = "SELECT countyname, time from counties where countyname = $1";

foreach ($counties as $county) {
    $result = pg_query_params($conn, $query, array($county));
    $row = pg_fetch_row($result);
    echo "$row[0]  $row[1]  \n";
}

请注意pg_query_params()的第三个参数是一个数组,因此即使只有一个参数,也必须放array($county)

您还可以使用数组作为参数执行一个查询。 在这种情况下,您应该对数组使用postgres语法,并将其作为文本变量传递给查询。

$counties = "array['Jackson', 'Josephine', 'Curry']";
$query = "SELECT countyname, time from counties where countyname = any ($counties)";
echo "$query\n\n";
$result = pg_query($conn, $query);
while ($row = pg_fetch_row($result)) {
    echo "$row[0]  $row[1]  \n";
}

答案 1 :(得分:1)

如果您只需要知道数组中指定的每个县有多少个点,那么您可以通过一次调用数据库来执行以下操作:

SELECT countyname, count(*)
FROM counties
JOIN ltg_data ON ST_contains(counties.the_geom, ltg_data.ltg_geom)
WHERE countyname = ANY ($counties)
AND time >= now() - interval '40 days'
GROUP BY countyname;

这比单独调用更有效,并且只返回县名的单个实例,而不是每个检索到的记录一个。如果你在国家克拉马斯(Klamath)有1000分,那么你就可以归还#34; Klamath&#34;只有一次,而不是1000次。此外,php不必计算查询结果的长度。总而言之,更清洁,更快。

还要注意JOIN语法与PostGIS函数调用的结合。