2012-06-13 52 views
2

在CentOS 6.2上使用PHP 5.3.3,PostgreSQL 8.4.11,pgbouncer 1.3.4(在session模式下)我試圖執行幾個SQL命令並獲取結果由一個PHP腳本。錯誤「無法將多個命令插入預準備語句」

當我從腳本中的命令複製到PSQL提示他們工作得很好,並返回12行:

enter image description here

但是,當我從劇本來看,我得到的錯誤:

SQLSTATE[42601]: Syntax error: 7 ERROR: cannot insert multiple commands into a prepared statement 

請幫忙嗎?

下面是我失敗的PHP代碼,我嘗試使用$db->query()代替$db->prepare/execute太:

try { 
     $options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); 
     $db = new PDO(sprintf('pgsql:host=%s port=%u; dbname=%s', 
       DBHOST, DBPORT, DBNAME), DBUSER, DBPASS, $options); 

     $sth = $db->prepare(" 
      start transaction; 
      create temporary table temp_ids (id varchar not null) on commit drop; 
      insert into temp_ids (id) 
        select id 
        from pref_money 
        where yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW') 
        order by money 
        desc limit 10; 

      create temporary table temp_rids (rid integer not null) on commit drop; 
      insert into temp_rids (rid) 
        select rid 
        from pref_cards 
        where stamp > now() - interval '1 day' and 
        id in (select id from temp_ids) and 
        bid = 'Мизер' and 
        trix > 0; 

      SELECT r.rid, r.cards, to_char(r.stamp, 'DD.MM.YYYY HH24:MI') as day, 
        c.bid, c.trix, c.pos, c.money, c.last_ip, c.quit, 
        u.id, u.first_name, u.avatar, u.female, u.city, u.vip > CURRENT_DATE as vip 
        FROM pref_rounds r, pref_cards c, pref_users u 
        WHERE u.id = c.id and 
         r.rid = c.rid and 
         r.rid in (select rid from temp_rids) 
        order by rid, pos; 
      commit; 
     "); 
     $sth->execute(); 
     while ($row = $sth->fetch(PDO::FETCH_ASSOC)) { 
       # stuff a JSON object 
     } 
} catch (Exception $e) { 
     exit('Database problem: ' . $e->getMessage()); 
} 

回答

1

我在郵件列表中有一個小貼士來擺脫臨時工。表和它的作品對我來說:

select r.rid, r.cards, to_char(r.stamp, 'DD.MM.YYYY HH24:MI') as day, 
    c.bid, c.trix, c.pos, c.money, c.last_ip, c.quit, 
    u.id, u.first_name, u.avatar, u.female, u.city, u.vip > CURRENT_DATE as vip 
    from pref_rounds r, pref_cards c, pref_users u 
    where u.id = c.id and 
    r.rid = c.rid and 
    r.rid in (
     select rid 
      from pref_cards 
      where stamp > CURRENT_TIMESTAMP - interval '1 day' and 
      id in (
       select id 
        from pref_money 
        where yw = to_char(CURRENT_TIMESTAMP - interval '1 week', 'IYYY-IW') 
        order by money 
        desc limit 10) and 
        bid = 'Misere' and 
        trix > 0 
    ) 
    order by r.rid, c.pos 
2

試試這個,開始一個事務,並分割你的querys了,因爲你不插入值從用戶輸入不存在需要準備查詢,也因爲你不期待從任何結果,但最後一個執行沒問題。在最後一個你可以使用query()。如果發生異常,則可以回滾更改。

<?php 
try { 
    $options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); 
    $db = new PDO(sprintf('pgsql:host=%s port=%u; dbname=%s', 
    DBHOST, DBPORT, DBNAME), DBUSER, DBPASS, $options); 
    //Transaction 
    $db->beginTransaction(); 

    $db->exec("create temporary table temp_ids (id varchar not null) on commit drop;"); 

    $db->exec("insert into temp_ids (id) 
        select id 
        from pref_money 
        where yw = to_char(current_timestamp - interval '1 week', 'IYYY-IW') 
        order by money 
        desc limit 10;"); 

    $db->exec("create temporary table temp_rids (rid integer not null) on commit drop;"); 

    $db->exec("insert into temp_rids (rid) 
        select rid 
        from pref_cards 
        where stamp > now() - interval '1 day' and 
        id in (select id from temp_ids) and 
        bid = 'Мизер' and 
        trix > 0;"); 
    //Commit changes before doing your select 
    $db->commit(); 

    $sth = $db->query("SELECT r.rid, r.cards, to_char(r.stamp, 'DD.MM.YYYY HH24:MI') as day, 
        c.bid, c.trix, c.pos, c.money, c.last_ip, c.quit, 
        u.id, u.first_name, u.avatar, u.female, u.city, u.vip > CURRENT_DATE as vip 
        FROM pref_rounds r, pref_cards c, pref_users u 
        WHERE u.id = c.id and 
         r.rid = c.rid and 
         r.rid in (select rid from temp_rids) 
        order by rid, pos;"); 


    while ($row = $sth->fetch(PDO::FETCH_ASSOC)) { 
     # stuff a JSON object 
    } 
} catch (Exception $e) { 
    //Transaction rollback 
    $db->rollback(); 
    exit('Database problem: ' . $e->getMessage()); 
} 

?> 
+0

我得到的錯誤:'不確定表:7 ERROR:關係 「temp_rids」 不存在第7行:r.rid中(選擇temp_rids RID)'(即使我禁用pgbouncer)。 –