使用多个查询的复杂Wordpress查询

时间:2013-08-15 05:47:46

标签: php mysql wordpress

所以我有一个查询,如果我直接在MySQL中运行,但是如果我通过Wordpress $ wpdb-> query()运行它就会失败。

如果我将$ qry回显到页面并将其复制并粘贴到phpMyAdmin中,例如我得到了我想要的所有结果。但是在Wordpress中我遇到了错误。

错误: WordPress数据库错误:[您的SQL语法有错误;检查与MySQL服务器版本对应的手册,以便在'SELECT *,ROUND(3963.0 * ACOS(SIN(38.580983 * PI()/ 180)* SIN(lat * PI()/ 18')附近使用正确的语法21]

查询:

CREATE TEMPORARY TABLE tmp_locations_tbl
SELECT post.ID, 
        post.post_name, 
        lat_meta.meta_value AS lat, 
        lng_meta.meta_value AS lng, 
        address_meta.meta_value AS address
FROM wp_posts AS post, 
        wp_postmeta AS lat_meta, 
        wp_postmeta AS lng_meta, 
        wp_postmeta AS address_meta

WHERE post.ID = lat_meta.post_id 
AND post.ID = lat_meta.post_id 
AND post.ID = lng_meta.post_id 
AND lat_meta.meta_key = 'geo_latitude' 
AND lng_meta.meta_key = 'geo_longitude' 
AND address_meta.meta_key = 'address'

LIMIT 0, 5000;

SELECT *, 
ROUND( 3963.0 * ACOS( SIN( 38.580983*PI()/180 ) * SIN( lat*PI()/180 ) + COS( 38.580983*PI()/180 ) * COS( lat*PI()/180 ) * COS( (lng*PI()/180) - (-121.4931*PI()/180) ) ) , 1) 
AS distance
FROM tmp_locations_tbl
HAVING distance < 25
ORDER BY distance ASC
LIMIT 0, 200;

显然它不喜欢';' - 或者我认为。但为什么直接在MySQL而不是Wordpress中运行良好。有趣的是,如果我删除';'从分隔两个查询的查询中,Wordpress没有返回正确的结果和MySQL,通过phpMyAdmin说这是一个不正确的查询。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:3)

这似乎是PHP本身的限制,请参阅this post on the Wordpress forums

我遇到了同样的问题并最终创建了一个自定义函数来完成这项工作,我将它粘贴在这里以防它对某人有用。该函数相当简单,因为它做了一些假设,但应该很容易修改它以定制不同的需求。具体来说,它假设:

  • 所有语句都是插入和更新,没有数据要返回。
  • 语句以行结束序列分隔。
  • 声明附在交易中。

这是功能:

function execute_multiline_sql($sql) {
    global $wpdb;
    $sqlParts = array_filter(explode("\r\n", $sql));
    foreach($sqlParts as $part) {
        $wpdb->query($part);
        if($wpdb->last_error != '') {
            $error = new WP_Error("dberror", __("Database query error"), $wpdb->last_error);
            $wpdb->query("rollback;");
            return $error;
        }
    }
    return true;
}

用法示例:

$sql = "start transaction;\r\n" .
       "insert into ...;\r\n" .
       "update ...;\r\n" .
       "commit;\r\n"
       ;

$result = execute_multiline_sql($sql);
if(is_wp_error($result)) {
    //Fail!
}

答案 1 :(得分:1)

您的代码不是显示一条SQL语句,而是显示两条:

  1. CREATE TEMPORARY [...] LIMIT 0, 500;
  2. SELECT *, ROUND[...] LIMIT 0, 200;
  3. 据我记忆,$wbdb->query()一次只接受一个语句(至少codex article没有指出它是专为批量查询而设计的,我还没检查过类代码验证它)。

    尝试将这些语句放在两个不同的变量中,然后依次运行它们,如下所示:

    $SQL1 = "CREATE TEMPORARY [...] LIMIT 0, 500";
    $SQL2 = "SELECT *, ROUND[...] LIMIT 0, 200";
    
    $wpdb->query( $SQL1 );   
    $wpdb->query( $SQL2 );